From eebdcf85cbadefcaee9521d7bb65dc700de5a22e Mon Sep 17 00:00:00 2001 From: nerd73 Date: Sun, 17 May 2020 19:28:40 -0600 Subject: [PATCH 01/12] Made writing to MSR 0x8B GPF on Intel Pentium/Pentium MMX Windows Vista now (correctly) no longer works on these CPUs. IDT WinChip, AMD K6, VIA Cyrix III, and Intel P6 family CPUs are not affected. --- src/cpu_common/cpu.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cpu_common/cpu.c b/src/cpu_common/cpu.c index 0c643f9d9..8e88e9f4b 100644 --- a/src/cpu_common/cpu.c +++ b/src/cpu_common/cpu.c @@ -3149,6 +3149,10 @@ void cpu_WRMSR() case 0x10: tsc = EAX | ((uint64_t)EDX << 32); break; + case 0x8B: + cpu_log("WRMSR: Invalid MSR: 0x8B/n"); /*Needed for Vista to correctly break on Pentium*/ + x86gpf(NULL, 0); + break; } break; #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) From 518147bc2c4903ab351b09e8999b3cbd0ce50dfd Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sun, 17 May 2020 23:17:51 -0300 Subject: [PATCH 02/12] Calibrate hardware monitor values on Socket 7 boards --- src/machine/m_at_socket7_s7.c | 129 +++++++++------------------------- 1 file changed, 32 insertions(+), 97 deletions(-) diff --git a/src/machine/m_at_socket7_s7.c b/src/machine/m_at_socket7_s7.c index d0cadb632..959d7248b 100644 --- a/src/machine/m_at_socket7_s7.c +++ b/src/machine/m_at_socket7_s7.c @@ -61,7 +61,7 @@ machine_at_chariot_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 2, 1); pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 3, 2, 1); @@ -91,7 +91,7 @@ machine_at_mr586_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 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); @@ -488,7 +488,7 @@ machine_at_p55tvp4_init(const machine_t *model) pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); @@ -682,13 +682,11 @@ machine_at_tx97_init(const machine_t *model) { /* fan speeds */ 3000, /* Chassis */ 3000, /* CPU */ - 3000, /* Power */ - 0 + 3000 /* Power */ }, { /* temperatures */ 30, /* MB */ 0, /* unused */ - 27, /* CPU */ - 0 + 8 /* CPU */ }, { /* voltages */ 3300, /* VCORE (3.3V by default) */ 0, /* unused */ @@ -696,20 +694,22 @@ machine_at_tx97_init(const machine_t *model) RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */ RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */ RESISTOR_DIVIDER(12000, 853, 347), /* -12V (divider values bruteforced) */ - RESISTOR_DIVIDER(5000, 1, 2), /* -5V (divider values bruteforced) */ - 0 + RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */ } }; /* Pentium, Pentium OverDrive MMX, Pentium Mobile MMX: 3.3V (real Pentium Mobile MMX is 2.45V). Pentium MMX: 2.8 V. AMD K6 Model 6: 2.9 V for 166/200, 3.2 V for 233. AMD K6 Model 7: 2.2 V. */ - if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUMMMX) - machine_hwm.voltages[0] = 2800; /* set higher VCORE (2.8V) for Pentium MMX */ - else if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_K6) - machine_hwm.voltages[0] = 2200; /* set higher VCORE (2.8V) for Pentium MMX */ - else if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_K6_2) - machine_hwm.voltages[0] = 2200; /* set higher VCORE (2.8V) for Pentium MMX */ + switch (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) { + case CPU_PENTIUMMMX: + machine_hwm.voltages[0] = 2800; + break; + case CPU_K6: + case CPU_K6_2: + machine_hwm.voltages[0] = 2200; + break; + } hwm_set_values(machine_hwm); device_add(&w83781d_device); @@ -745,31 +745,6 @@ machine_at_ym430tx_init(const machine_t *model) device_add(&w83977tf_device); device_add(&intel_flash_bxt_device); - hwm_values_t machine_hwm = { - { /* fan speeds */ - 3000, /* Chassis */ - 3000, /* CPU */ - 3000, /* Power */ - 0 - }, { /* temperatures */ - 30, /* MB */ - 0, /* unused */ - 27, /* CPU */ - 0 - }, { /* voltages */ - 2050, /* VCORE (2.05V by default) */ - 0, /* unused */ - 3300, /* +3.3V */ - RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */ - RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */ - RESISTOR_DIVIDER(12000, 853, 347), /* -12V (divider values bruteforced) */ - RESISTOR_DIVIDER(5000, 1, 2), /* -5V (divider values bruteforced) */ - 0 - } - }; - hwm_set_values(machine_hwm); - device_add(&w83781d_device); - return ret; } @@ -830,41 +805,6 @@ machine_at_807ds_init(const machine_t *model) device_add(&um8669f_device); /*Placeholder for ITE 8679*/ device_add(&intel_flash_bxt_device); - hwm_values_t machine_hwm = { - { /* fan speeds */ - 3000, /* Chassis */ - 3000, /* CPU */ - 3000, /* Power */ - 0 - }, { /* temperatures */ - 30, /* MB */ - 0, /* unused */ - 27, /* CPU */ - 0 - }, { /* voltages */ - 3300, /* VCORE (3.3V by default) */ - 0, /* unused */ - 3300, /* +3.3V */ - RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */ - RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */ - RESISTOR_DIVIDER(12000, 853, 347), /* -12V (divider values bruteforced) */ - RESISTOR_DIVIDER(5000, 1, 2), /* -5V (divider values bruteforced) */ - 0 - } - }; - /* Pentium, Pentium OverDrive MMX, Pentium Mobile MMX: 3.3V (real Pentium Mobile MMX is 2.45V). - Pentium MMX: 2.8 V. - AMD K6 Model 6: 2.9 V for 166/200, 3.2 V for 233. - AMD K6 Model 7: 2.2 V. */ - if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUMMMX) - machine_hwm.voltages[0] = 2800; /* set higher VCORE (2.8V) for Pentium MMX */ - else if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_K6) - machine_hwm.voltages[0] = 2200; /* set higher VCORE (2.8V) for Pentium MMX */ - else if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_K6_2) - machine_hwm.voltages[0] = 2200; /* set higher VCORE (2.8V) for Pentium MMX */ - hwm_set_values(machine_hwm); - device_add(&w83781d_device); - return ret; } #endif @@ -897,38 +837,36 @@ machine_at_p5mms98_init(const machine_t *model) hwm_values_t machine_hwm = { { /* fan speeds */ - 3000, /* Chassis */ + 3000, /* Thermal */ 3000, /* CPU */ - 3000, /* Power */ - 0 + 3000 /* Chassis */ }, { /* temperatures */ - 30, /* MB */ - 0, /* unused */ - 27, /* CPU */ - 0 + 28 /* CPU (locked at 28?) */ }, { /* voltages */ 3300, /* VCORE (3.3V by default) */ - 0, /* unused */ + 3300, /* VIO (3.3V) */ 3300, /* +3.3V */ RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */ RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */ RESISTOR_DIVIDER(12000, 853, 347), /* -12V (divider values bruteforced) */ - RESISTOR_DIVIDER(5000, 1, 2), /* -5V (divider values bruteforced) */ - 0 + RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */ } }; /* Pentium, Pentium OverDrive MMX, Pentium Mobile MMX: 3.3V (real Pentium Mobile MMX is 2.45V). Pentium MMX: 2.8 V. AMD K6 Model 6: 2.9 V for 166/200, 3.2 V for 233. AMD K6 Model 7: 2.2 V. */ - if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUMMMX) - machine_hwm.voltages[0] = 2800; /* set higher VCORE (2.8V) for Pentium MMX */ - else if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_K6) - machine_hwm.voltages[0] = 2200; /* set higher VCORE (2.8V) for Pentium MMX */ - else if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_K6_2) - machine_hwm.voltages[0] = 2200; /* set higher VCORE (2.8V) for Pentium MMX */ + switch (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) { + case CPU_PENTIUMMMX: + machine_hwm.voltages[0] = 2800; + break; + case CPU_K6: + case CPU_K6_2: + machine_hwm.voltages[0] = 2200; + break; + } hwm_set_values(machine_hwm); - device_add(&w83781d_device); + device_add(&lm78_device); return ret; } @@ -951,14 +889,13 @@ machine_at_ficva502_init(const machine_t *model) 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(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); device_add(&via_vpx_device); device_add(&via_vt82c586b_device); device_add(&keyboard_ps2_pci_device); device_add(&fdc37c669_device); device_add(&sst_flash_29ee010_device); - spd_register(SPD_TYPE_SDRAM, 0xF, 256); return ret; } @@ -981,14 +918,13 @@ machine_at_ficpa2012_init(const machine_t *model) 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(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); device_add(&via_vp3_device); device_add(&via_vt82c586b_device); device_add(&keyboard_ps2_pci_device); device_add(&w83877f_device); device_add(&sst_flash_39sf010_device); - spd_register(SPD_TYPE_SDRAM, 0xF, 64); return ret; } @@ -1018,7 +954,6 @@ machine_at_advanceii_init(const machine_t *model) device_add(&keyboard_ps2_pci_device); device_add(&um8669f_device); //IT8661F device_add(&sst_flash_39sf010_device); - spd_register(SPD_TYPE_SDRAM, 0xF, 64); return ret; } From 97b562815f64996df225a44c3d75e3b547df8591 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sun, 17 May 2020 23:23:47 -0300 Subject: [PATCH 03/12] Add SPD to 430TX boards --- src/machine/m_at_socket7_s7.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/machine/m_at_socket7_s7.c b/src/machine/m_at_socket7_s7.c index 959d7248b..c38fecbd4 100644 --- a/src/machine/m_at_socket7_s7.c +++ b/src/machine/m_at_socket7_s7.c @@ -645,6 +645,7 @@ machine_at_p55xb2_init(const machine_t *model) device_add(&keyboard_ps2_pci_device); // device_add(&ali_m513x_device); device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); return ret; } @@ -677,6 +678,7 @@ machine_at_tx97_init(const machine_t *model) device_add(&keyboard_ps2_pci_device); device_add(&w83877tf_acorp_device); device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); hwm_values_t machine_hwm = { { /* fan speeds */ @@ -744,6 +746,7 @@ machine_at_ym430tx_init(const machine_t *model) device_add(&keyboard_ps2_pci_device); device_add(&w83977tf_device); device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); return ret; } @@ -774,6 +777,7 @@ machine_at_586t2_init(const machine_t *model) device_add(&keyboard_ps2_pci_device); device_add(&um8669f_device); /*Placeholder for ITE 8679*/ device_add(&sst_flash_29ee010_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); return ret; } @@ -804,6 +808,7 @@ machine_at_807ds_init(const machine_t *model) device_add(&keyboard_ps2_ami_pci_device); device_add(&um8669f_device); /*Placeholder for ITE 8679*/ device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); return ret; } @@ -834,6 +839,7 @@ machine_at_p5mms98_init(const machine_t *model) device_add(&keyboard_ps2_ami_pci_device); device_add(&w83977tf_device); device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); hwm_values_t machine_hwm = { { /* fan speeds */ From 671e532599eb515f998cfe7cdd40b36bc3faaa60 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 18 May 2020 00:08:32 -0300 Subject: [PATCH 04/12] Calibrate hardware monitor values on the remaining boards --- src/machine/m_at_slot1.c | 71 ++++++++++++++++-------------------- src/machine/m_at_slot2.c | 19 ++++------ src/machine/m_at_socket370.c | 39 +++++++------------- 3 files changed, 53 insertions(+), 76 deletions(-) diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index 401b4e305..65838fd21 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -154,13 +154,11 @@ machine_at_p2bls_init(const machine_t *model) { /* fan speeds */ 3000, /* Chassis */ 3000, /* CPU */ - 3000, /* Power */ - 0 + 3000 /* Power */ }, { /* temperatures */ 30, /* MB */ 0, /* unused */ - 27, /* CPU */ - 0 + 27 /* CPU */ }, { /* voltages */ 2050, /* VCORE (2.05V by default) */ 0, /* unused */ @@ -168,8 +166,7 @@ machine_at_p2bls_init(const machine_t *model) RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */ RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */ RESISTOR_DIVIDER(12000, 853, 347), /* -12V (divider values bruteforced) */ - RESISTOR_DIVIDER(5000, 1, 2), /* -5V (divider values bruteforced) */ - 0 + RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */ } }; if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUM2) @@ -214,13 +211,11 @@ machine_at_p3bf_init(const machine_t *model) { /* fan speeds */ 3000, /* Chassis */ 3000, /* CPU */ - 3000, /* Power */ - 0 + 3000 /* Power */ }, { /* temperatures */ 30, /* MB */ 0, /* unused */ - 30, /* CPU */ - 0 + 30 /* CPU */ }, { /* voltages */ 2050, /* VCORE (2.05V by default) */ 0, /* unused */ @@ -228,8 +223,7 @@ machine_at_p3bf_init(const machine_t *model) RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */ RESISTOR_DIVIDER(12000, 3, 1), /* +12V (divider values bruteforced) */ RESISTOR_DIVIDER(12000, 59, 20), /* -12V (divider values bruteforced) */ - RESISTOR_DIVIDER(5000, 1, 2), /* -5V (divider values bruteforced) */ - 0 + RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */ } }; if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUM2) @@ -255,13 +249,13 @@ machine_at_bf6_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 3, 1, 2); - pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 1, 4, 3); - pci_register_slot(0x08, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 3, 1, 2); + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 1, 4, 3); + pci_register_slot(0x08, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); pci_register_slot(0x01, PCI_CARD_NORMAL, 1, 2, 3, 4); device_add(&i440bx_device); @@ -277,11 +271,11 @@ machine_at_bf6_init(const machine_t *model) int machine_at_p6sba_init(const machine_t *model) { - /* - AMI 440BX Board. - doesn't like the i686 CPU's. - 10 -> D3 -> D1 POST. Probably KBC related. - */ + /* + AMI 440BX Board. + doesn't like the i686 CPU's. + 10 -> D3 -> D1 POST. Probably KBC related. + */ int ret; @@ -312,24 +306,21 @@ machine_at_p6sba_init(const machine_t *model) hwm_values_t machine_hwm = { { /* fan speeds */ - 3000, /* Chassis */ - 3000, /* CPU */ - 3000, /* Power */ - 0 + 3000, /* CPU1 */ + 0, /* CPU2 */ + 3000 /* Thermal Control */ }, { /* temperatures */ - 30, /* MB */ 0, /* unused */ - 28, /* CPU */ - 0 + 30, /* CPU1 */ + 0 /* unused (CPU2?) */ }, { /* voltages */ - 2050, /* VCORE (2.05V by default) */ - 0, /* unused */ + 2050, /* CPU1 (2.05V by default) */ + 0, /* CPU2 */ 3300, /* +3.3V */ RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */ RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */ RESISTOR_DIVIDER(12000, 853, 347), /* -12V (divider values bruteforced) */ - RESISTOR_DIVIDER(5000, 1, 2), /* -5V (divider values bruteforced) */ - 0 + RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */ } }; if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUM2) @@ -359,12 +350,12 @@ machine_at_tsunamiatx_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x10, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x10, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x01, PCI_CARD_NORMAL, 1, 2, 3, 4); device_add(&i440bx_device); device_add(&piix4e_device); diff --git a/src/machine/m_at_slot2.c b/src/machine/m_at_slot2.c index 1e220a000..b85ce9a83 100644 --- a/src/machine/m_at_slot2.c +++ b/src/machine/m_at_slot2.c @@ -83,24 +83,21 @@ machine_at_s2dge_init(const machine_t *model) hwm_values_t machine_hwm = { { /* fan speeds */ - 3000, /* Chassis */ - 3000, /* CPU */ - 3000, /* Power */ - 0 + 3000, /* CPU1 */ + 0, /* CPU2 */ + 3000 /* Thermal Control */ }, { /* temperatures */ - 30, /* MB */ 0, /* unused */ - 28, /* CPU */ - 0 + 30, /* CPU1 */ + 20 /* unused (CPU2?) */ }, { /* voltages */ - 2050, /* VCORE (2.05V by default) */ - 0, /* unused */ + 2050, /* CPU1 (2.05V by default) */ + 0, /* CPU2 */ 3300, /* +3.3V */ RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */ RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */ RESISTOR_DIVIDER(12000, 853, 347), /* -12V (divider values bruteforced) */ - RESISTOR_DIVIDER(5000, 1, 2), /* -5V (divider values bruteforced) */ - 0 + RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */ } }; if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUM2) diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index ed93d9266..b0c75f80a 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -74,28 +74,23 @@ machine_at_s370slm_init(const machine_t *model) hwm_values_t machine_hwm = { { /* fan speeds */ - 3000, /* Chassis */ 3000, /* CPU */ - 3000, /* Power */ - 0 + 3000, /* Fan 2 */ + 3000 /* Chassis */ }, { /* temperatures */ - 30, /* MB */ 0, /* unused */ - 28, /* CPU */ - 0 + 30, /* CPU */ + 0 /* unused */ }, { /* voltages */ - 2050, /* VCORE (2.05V by default) */ + 2050, /* CPU1 (2.05V by default) */ 0, /* unused */ 3300, /* +3.3V */ RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */ RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */ RESISTOR_DIVIDER(12000, 853, 347), /* -12V (divider values bruteforced) */ - RESISTOR_DIVIDER(5000, 1, 2), /* -5V (divider values bruteforced) */ - 0 + RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */ } }; - if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUM2) - machine_hwm.voltages[0] = 2800; /* set higher VCORE (2.8V) for Klamath */ hwm_set_values(machine_hwm); device_add(&w83781d_device); @@ -137,13 +132,11 @@ machine_at_cubx_init(const machine_t *model) { /* fan speeds */ 3000, /* Chassis */ 3000, /* CPU */ - 3000, /* Power */ - 0 + 3000 /* Power */ }, { /* temperatures */ 30, /* MB */ 0, /* unused */ - 30, /* CPU */ - 0 + 30 /* CPU */ }, { /* voltages */ 2050, /* VCORE (2.05V by default) */ 0, /* unused */ @@ -151,8 +144,7 @@ machine_at_cubx_init(const machine_t *model) RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */ RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */ RESISTOR_DIVIDER(12000, 59, 20), /* -12V (divider values bruteforced) */ - RESISTOR_DIVIDER(5000, 1, 2), /* -5V (divider values bruteforced) */ - 0 + RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */ } }; hwm_set_values(machine_hwm); @@ -197,9 +189,6 @@ machine_at_atc7020bxii_init(const machine_t *model) int machine_at_63a_init(const machine_t *model) { - - /* 440ZX Board. 440ZX is basically an underpowered 440BX. There no - difference between to chipsets other than the name. */ int ret; ret = bios_load_linear(L"roms/machines/63a1/63a-q3.bin", @@ -245,16 +234,16 @@ machine_at_apas3_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); pci_register_slot(0x01, PCI_CARD_NORMAL, 1, 2, 3, 4); device_add(&via_apro_device); device_add(&via_vt82c586b_device); device_add(&fdc37c669_device); - device_add(&keyboard_ps2_pci_device); + device_add(&keyboard_ps2_pci_device); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); From 68151c03262f90ea6b849f3180e19546edc91ea0 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 18 May 2020 00:11:19 -0300 Subject: [PATCH 05/12] Machine table indentation fixes --- src/machine/machine_table.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 7be984c60..16f7b71f9 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -266,11 +266,11 @@ const machine_t machines[] = { { "[Socket 7 TX] Iwill P55XB2", "p55xb2", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_p55xb2_init, NULL }, { "[Socket 7 TX] PC Partner TXA807DS", "807ds", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_807ds_init, NULL }, #endif - { "[Socket 7 TX] SuperMicro P5MMS98", "p5mms98", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_p5mms98_init, NULL }, + { "[Socket 7 TX] Supermicro P5MMS98", "p5mms98", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_p5mms98_init, NULL }, /* Apollo VPX */ - { "[Socket 7 VPX] FIC VA-502", "ficva502", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_ficva502_init, NULL }, + { "[Socket 7 VPX] FIC VA-502", "ficva502", 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 */ { "[Socket 7 VP3] FIC PA-2012", "ficpa2012", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_ficpa2012_init, NULL }, @@ -307,20 +307,20 @@ const machine_t machines[] = { { "[Slot 1 BX] ASUS P3B-F", "p3bf", {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_p3bf_init, NULL }, { "[Slot 1 BX] ABit BF6", "bf6", {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_bf6_init, NULL }, #if defined(DEV_BRANCH) && defined(NO_SIO) - { "[Slot 1 BX] Tyan Tsunami ATX", "tsunamiatx", {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_tsunamiatx_init, NULL }, + { "[Slot 1 BX] Tyan Tsunami ATX", "tsunamiatx", {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_tsunamiatx_init, NULL }, #endif - { "[Slot 1 BX] Supermicro P6SBA", "p6sba", {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_p6sba_init, NULL }, + { "[Slot 1 BX] Supermicro P6SBA", "p6sba", {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_p6sba_init, NULL }, /* Slot 2 machines */ /* 440GX */ #if defined(DEV_BRANCH) && defined(NO_SIO) - { "[Slot 2 GX] Supermicro S2DGE", "s2dge", {{"Intel", cpus_Xeon}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_s2dge_init, NULL }, + { "[Slot 2 GX] Supermicro S2DGE", "s2dge", {{"Intel", cpus_Xeon}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_s2dge_init, NULL }, #endif /* PGA370 machines */ /* 440LX */ #if defined(DEV_BRANCH) && defined(NO_SIO) - { "[Socket 370 BX] Supermicro S370SLM", "s370slm", {{"Intel", cpus_Celeron}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_s370slm_init, NULL }, + { "[Socket 370 LX] Supermicro S370SLM", "s370slm", {{"Intel", cpus_Celeron}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_s370slm_init, NULL }, #endif /* 440BX */ { "[Socket 370 BX] ASUS CUBX", "cubx", {{"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 }, From fe4ff767a1f85d155156e3ffc3692511a69fcdf1 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 18 May 2020 00:11:31 -0300 Subject: [PATCH 06/12] Hardware monitor refactoring --- src/hwm_lm78.c | 610 +++++++++++++++++++++++++++++++++++++ src/hwm_w83781d.c | 561 ---------------------------------- src/include/86box/hwm.h | 3 + src/win/Makefile.mingw | 2 +- src/win/Makefile_ndr.mingw | 2 +- 5 files changed, 615 insertions(+), 563 deletions(-) create mode 100644 src/hwm_lm78.c delete mode 100644 src/hwm_w83781d.c diff --git a/src/hwm_lm78.c b/src/hwm_lm78.c new file mode 100644 index 000000000..27c15fe8f --- /dev/null +++ b/src/hwm_lm78.c @@ -0,0 +1,610 @@ +/* + * 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. + * + * Emulation of the National Semiconductor LM78 hardware monitoring chip. + * + * + * + * Author: RichardG, + * + * Copyright 2020 RichardG. + */ +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include "cpu.h" +#include <86box/smbus.h> +#include <86box/hwm.h> + + +#define LM78_SMBUS 0x10000 +#define LM78_W83781D 0x20000 +#define LM78_AS99127F_REV1 0x40000 +#define LM78_AS99127F_REV2 0x80000 +#define LM78_AS99127F (LM78_AS99127F_REV1 | LM78_AS99127F_REV2) /* special mask covering both _REV1 and _REV2 */ +#define LM78_WINBOND (LM78_W83781D | LM78_AS99127F) /* special mask covering all Winbond variants */ +#define LM78_WINBOND_VENDOR_ID ((dev->local & LM78_AS99127F_REV1) ? 0x12c3 : 0x5ca3) + +#define CLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a))) +#define LM78_RPM_TO_REG(r, d) ((r) ? CLAMP(1350000 / (r * d), 1, 255) : 0) +#define LM78_TEMP_TO_REG(t) ((t) << 8) +#define LM78_VOLTAGE_TO_REG(v) ((v) >> 4) + + +typedef struct { + uint32_t local; + hwm_values_t* values; + + uint8_t regs[256]; + uint8_t regs_bank1[7]; + uint8_t regs_bank2[7]; + uint8_t addr_register; + uint8_t data_register; + + uint8_t smbus_addr_main; + uint8_t smbus_addr_temp2; + uint8_t smbus_addr_temp3; + uint8_t hbacs; + uint8_t active_bank; +} lm78_t; + + +static uint8_t lm78_isa_read(uint16_t port, void *priv); +static uint8_t lm78_smbus_read_byte(uint8_t addr, void *priv); +static uint8_t lm78_smbus_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv); +static uint16_t lm78_smbus_read_word_cmd(uint8_t addr, uint8_t cmd, void *priv); +static uint8_t lm78_read(lm78_t *dev, uint8_t reg, uint8_t bank); +static void lm78_isa_write(uint16_t port, uint8_t val, void *priv); +static void lm78_smbus_write_byte(uint8_t addr, uint8_t val, void *priv); +static void lm78_smbus_write_byte_cmd(uint8_t addr, uint8_t cmd, uint8_t val, void *priv); +static void lm78_smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val, void *priv); +static uint8_t lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank); +static void lm78_reset(lm78_t *dev, uint8_t initialization); + + +#ifdef ENABLE_LM78_LOG +int lm78_do_log = ENABLE_LM78_LOG; + + +static void +lm78_log(const char *fmt, ...) +{ + va_list ap; + + if (lm78_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define lm78_log(fmt, ...) +#endif + + +static void +lm78_remap(lm78_t *dev) +{ + if (!(dev->local & LM78_SMBUS)) return; + + lm78_log("LM78: SMBus remap: main = %02Xh; temp2 = %02Xh; temp3 = %02Xh\n", dev->smbus_addr_main, dev->smbus_addr_temp2, dev->smbus_addr_temp3); + + smbus_removehandler(0x00, 0x80, + lm78_smbus_read_byte, lm78_smbus_read_byte_cmd, lm78_smbus_read_word_cmd, NULL, + lm78_smbus_write_byte, lm78_smbus_write_byte_cmd, lm78_smbus_write_word_cmd, NULL, + dev); + + if (dev->smbus_addr_main) smbus_sethandler(dev->smbus_addr_main, 1, + lm78_smbus_read_byte, lm78_smbus_read_byte_cmd, lm78_smbus_read_word_cmd, NULL, + lm78_smbus_write_byte, lm78_smbus_write_byte_cmd, lm78_smbus_write_word_cmd, NULL, + dev); + + if (dev->smbus_addr_temp2) smbus_sethandler(dev->smbus_addr_temp2, 1, + lm78_smbus_read_byte, lm78_smbus_read_byte_cmd, lm78_smbus_read_word_cmd, NULL, + lm78_smbus_write_byte, lm78_smbus_write_byte_cmd, lm78_smbus_write_word_cmd, NULL, + dev); + + if (dev->smbus_addr_temp3) smbus_sethandler(dev->smbus_addr_temp3, 1, + lm78_smbus_read_byte, lm78_smbus_read_byte_cmd, lm78_smbus_read_word_cmd, NULL, + lm78_smbus_write_byte, lm78_smbus_write_byte_cmd, lm78_smbus_write_word_cmd, NULL, + dev); +} + + +static uint8_t +lm78_isa_read(uint16_t port, void *priv) +{ + lm78_t *dev = (lm78_t *) priv; + uint8_t ret = 0xFF; + + switch (port & 0xf) { + case 0x5: + ret = (dev->addr_register & 0x7f); + break; + case 0x6: + ret = lm78_read(dev, dev->addr_register, dev->active_bank); + + if ((dev->active_bank == 0) && + ((dev->addr_register == 0x41) || (dev->addr_register == 0x43) || (dev->addr_register == 0x45) || (dev->addr_register == 0x56) || + ((dev->addr_register >= 0x60) && (dev->addr_register < 0x7f)))) { + /* auto-increment registers */ + dev->addr_register++; + } + break; + } + + return ret; +} + + +static uint8_t +lm78_smbus_read_byte(uint8_t addr, void *priv) +{ + lm78_t *dev = (lm78_t *) priv; + return lm78_smbus_read_byte_cmd(addr, dev->addr_register, priv); +} + + +static uint8_t +lm78_smbus_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv) +{ + lm78_t *dev = (lm78_t *) priv; + + uint8_t bank = 0; + if (addr == dev->smbus_addr_temp2) + bank = 1; + else if (addr == dev->smbus_addr_temp3) + bank = 2; + + return lm78_read(dev, cmd, bank); +} + + +static uint16_t +lm78_smbus_read_word_cmd(uint8_t addr, uint8_t cmd, void *priv) +{ + lm78_t *dev = (lm78_t *) priv; + uint8_t rethi = 0; + uint8_t retlo = 0; + uint8_t bank = 0; + + if ((dev->local & LM78_WINBOND) && ((addr == dev->smbus_addr_temp2) || (addr == dev->smbus_addr_temp3))) { + if (addr == dev->smbus_addr_temp2) + bank = 2; + else + bank = 3; + + switch (cmd & 0x3) { + case 0x0: /* temperature */ + rethi = lm78_read(dev, 0x50, bank); + retlo = lm78_read(dev, 0x51, bank); + break; + case 0x1: /* configuration */ + rethi = retlo = lm78_read(dev, 0x52, bank); + break; + case 0x2: /* Thyst */ + rethi = lm78_read(dev, 0x53, bank); + retlo = lm78_read(dev, 0x54, bank); + break; + case 0x3: /* Tos */ + rethi = lm78_read(dev, 0x55, bank); + retlo = lm78_read(dev, 0x56, bank); + break; + } + } else { + rethi = retlo = lm78_read(dev, cmd, bank); + } + + return (retlo << 8) | rethi; /* byte-swapped for some reason */ +} + + +static uint8_t +lm78_read(lm78_t *dev, uint8_t reg, uint8_t bank) +{ + uint8_t ret = 0; + + if ((dev->local & LM78_WINBOND) && ((reg >> 4) == 0x5) && (bank != 0)) { + /* bank-switched temperature registers */ + if (bank == 1) + ret = dev->regs_bank1[reg & 0x7]; + else + ret = dev->regs_bank2[reg & 0x7]; + } else { + /* regular registers */ + if ((reg == 0x4f) && (dev->local & LM78_WINBOND)) /* special case for two-byte vendor ID register */ + ret = (dev->hbacs ? (LM78_WINBOND_VENDOR_ID >> 8) : LM78_WINBOND_VENDOR_ID); + else if ((reg >= 0x60) && (reg <= 0x7f)) /* read auto-increment value RAM registers from their non-auto-increment locations */ + ret = dev->regs[reg & 0x3f]; + else if ((reg >= 0x80) && (reg <= 0x92)) /* AS99127F mirrors POST RAM to 80-92 */ + ret = dev->regs[reg - 0x7f]; + else + ret = dev->regs[reg]; + } + + lm78_log("LM78: read(%02x, %d) = %02x\n", reg, bank, ret); + + return ret; +} + + +static void +lm78_isa_write(uint16_t port, uint8_t val, void *priv) +{ + lm78_t *dev = (lm78_t *) priv; + + switch (port & 0xf) { + case 0x5: + dev->addr_register = (val & 0x7f); + break; + case 0x6: + lm78_write(dev, dev->addr_register, val, dev->active_bank); + + if ((dev->active_bank == 0) && + ((dev->addr_register == 0x41) || (dev->addr_register == 0x43) || (dev->addr_register == 0x45) || (dev->addr_register == 0x56) || + ((dev->addr_register >= 0x60) && (dev->addr_register < 0x7f)))) { + /* auto-increment registers */ + dev->addr_register++; + } + break; + } +} + + +static void +lm78_smbus_write_byte(uint8_t addr, uint8_t val, void *priv) +{ + lm78_t *dev = (lm78_t *) priv; + + dev->addr_register = val; +} + + +static void +lm78_smbus_write_byte_cmd(uint8_t addr, uint8_t cmd, uint8_t val, void *priv) +{ + lm78_t *dev = (lm78_t *) priv; + + lm78_write(dev, cmd, val, 0); +} + + +static void +lm78_smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val, void *priv) +{ + lm78_t *dev = (lm78_t *) priv; + uint8_t valhi = (val >> 8); + uint8_t vallo = (val & 0xff); + uint8_t bank = 0; + + if ((dev->local & LM78_WINBOND) && ((addr == dev->smbus_addr_temp2) || (addr == dev->smbus_addr_temp3))) { + if (addr == dev->smbus_addr_temp2) + bank = 2; + else + bank = 3; + + switch (cmd & 0x3) { + case 0x0: /* temperature */ + lm78_write(dev, 0x50, valhi, bank); + lm78_write(dev, 0x51, vallo, bank); + break; + case 0x1: /* configuration */ + lm78_write(dev, 0x52, vallo, bank); + break; + case 0x2: /* Thyst */ + lm78_write(dev, 0x53, valhi, bank); + lm78_write(dev, 0x54, vallo, bank); + break; + case 0x3: /* Tos */ + lm78_write(dev, 0x55, valhi, bank); + lm78_write(dev, 0x56, vallo, bank); + break; + break; + } + return; + } + + lm78_write(dev, cmd, vallo, bank); +} + + +static uint8_t +lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank) +{ + uint8_t remap = 0; + + if ((dev->local & LM78_WINBOND) && ((reg >> 4) == 0x5) && (bank != 0)) { + /* bank-switched temperature registers */ + switch (reg) { + case 0x50: case 0x51: + /* read-only registers */ + return 0; + } + + if (bank == 1) + dev->regs_bank1[reg & 0x7] = val; + else + dev->regs_bank2[reg & 0x7] = val; + + goto end; + } + + /* regular registers */ + switch (reg) { + case 0x41: case 0x42: case 0x4f: case 0x58: + case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29: case 0x2a: + case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: case 0x68: case 0x69: case 0x6a: + /* read-only registers */ + return 0; + case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: + /* Winbond-only registers */ + if (!(dev->local & LM78_WINBOND)) + return 0; + break; + } + + if ((reg >= 0x60) && (reg <= 0x7f)) /* write auto-increment value RAM registers to their non-auto-increment locations */ + dev->regs[reg & 0x3f] = val; + else if ((reg >= 0x80) && (reg <= 0x92)) /* AS99127F mirrors POST RAM to 80-92 */ + dev->regs[reg & 0x7f] = val; + else + dev->regs[reg] = val; + + switch (reg) { + case 0x40: + if (val & 0x80) { + /* INITIALIZATION bit resets all registers except main SMBus address */ + lm78_reset(dev, 1); + } + break; + case 0x47: + /* update FAN1/FAN2 values to match the new divisor */ + dev->regs[0x28] = LM78_RPM_TO_REG(dev->values->fans[0], 1 << ((dev->regs[0x47] >> 4) & 0x3)); + dev->regs[0x29] = LM78_RPM_TO_REG(dev->values->fans[1], 1 << ((dev->regs[0x47] >> 6) & 0x3)); + break; + case 0x48: + /* set main SMBus address */ + if (dev->local & LM78_SMBUS) { + dev->smbus_addr_main = (dev->regs[0x48] & 0x7f); + remap = 1; + } + break; + case 0x49: + if (!(dev->local & LM78_WINBOND)) { + if (val & 0x20) { + /* Chip Reset bit (LM78 only) resets all registers */ + lm78_reset(dev, 0); + } else { + dev->regs[0x49] = 0x40; + } + } else { + dev->regs[0x49] &= 0x01; + } + break; + case 0x4a: + /* set TEMP2 and TEMP3 SMBus addresses (Winbond only) */ + if (dev->local & LM78_SMBUS) { + /* DIS_T2 and DIS_T3 bit disable those interfaces */ + if (dev->regs[0x4a] & 0x08) + dev->smbus_addr_temp2 = 0x00; + else + dev->smbus_addr_temp2 = (0x48 + (dev->regs[0x4a] & 0x7)); + if (dev->regs[0x4a] & 0x80) + dev->smbus_addr_temp3 = 0x00; + else + dev->smbus_addr_temp3 = (0x48 + ((dev->regs[0x4a] >> 4) & 0x7)); + remap = 1; + } + break; + case 0x4b: + /* update FAN3 value to match the new divisor */ + dev->regs[0x2a] = LM78_RPM_TO_REG(dev->values->fans[2], 1 << ((dev->regs[0x4b] >> 6) & 0x3)); + break; + case 0x4e: + dev->hbacs = (dev->regs[0x4e] & 0x80); + /* BANKSEL[0:2] is a bitfield according to the datasheet, but not in reality */ + dev->active_bank = (dev->regs[0x4e] & 0x07); + break; + case 0x87: + /* fixes AS99127F boards hanging after save & exit, probably a reset register */ + if ((dev->local & LM78_AS99127F) && (val == 0x01)) { + lm78_log("LM78: Reset requested through AS99127F\n"); + resetx86(); + } + break; + } + + if (remap) + lm78_remap(dev); + +end: + lm78_log("LM78: write(%02x, %d) = %02x\n", reg, bank, val); + + return 1; +} + + +static void +lm78_reset(lm78_t *dev, uint8_t initialization) +{ + memset(dev->regs, 0, 256); + memset(dev->regs + 0xc0, 0xff, 32); /* C0-DF are 0xFF at least on the AS99127F */ + memset(dev->regs_bank1, 0, 6); + memset(dev->regs_bank2, 0, 6); + + uint8_t i; + for (i = 0; i <= 6; i++) + dev->regs[0x20 + i] = LM78_VOLTAGE_TO_REG(dev->values->voltages[i]); + dev->regs[0x27] = dev->values->temperatures[0]; + for (i = 0; i <= 2; i++) + dev->regs[0x28 + i] = LM78_RPM_TO_REG(dev->values->fans[i], 2); + dev->regs[0x40] = 0x08; + dev->regs[0x46] = 0x40; + dev->regs[0x47] = 0x50; + if (dev->local & LM78_SMBUS) { + if (!initialization) /* don't reset main SMBus address if the reset was triggered by the INITIALIZATION bit */ + dev->smbus_addr_main = 0x2d; + dev->regs[0x48] = dev->smbus_addr_main; + if (dev->local & LM78_WINBOND) { + dev->regs[0x4a] = 0x01; + dev->smbus_addr_temp2 = (0x48 + (dev->regs[0x4a] & 0x7)); + dev->smbus_addr_temp3 = (0x48 + ((dev->regs[0x4a] >> 4) & 0x7)); + } else { + dev->smbus_addr_temp2 = dev->smbus_addr_temp3 = 0x00; + } + } else { + dev->regs[0x48] = 0x00; + if (dev->local & LM78_WINBOND) + dev->regs[0x4a] = 0x88; + dev->smbus_addr_temp2 = dev->smbus_addr_temp3 = 0x00; + } + if (dev->local & LM78_WINBOND) { + dev->regs[0x49] = 0x02; + dev->regs[0x4b] = 0x44; + dev->regs[0x4c] = 0x01; + dev->regs[0x4d] = 0x15; + dev->regs[0x4e] = 0x80; + dev->hbacs = (dev->regs[0x4e] & 0x80); + dev->regs[0x4f] = (LM78_WINBOND_VENDOR_ID >> 8); + dev->regs[0x57] = 0x80; + + /* + * Initialize proprietary registers on the AS99127F. The BIOS accesses some + * of these on boot through read_byte_cmd on the TEMP2 address, hanging on + * POST code C1 if they're set to 0. There's no documentation on what these + * are for. The following values were dumped from a live, initialized + * AS99127F Rev. 2 on a P4B motherboard, and they seem to work well enough. + */ + if (dev->local & LM78_AS99127F) { + /* 0x00 appears to mirror IN2 Low Limit */ + dev->regs[0x01] = dev->regs[0x23]; /* appears to mirror IN3 */ + dev->regs[0x02] = LM78_VOLTAGE_TO_REG(2800); /* appears to be a "maximum VCORE" of some kind; mirrors VCORE on the P4 board, but the P3 boards require this to read 2.8V */ + dev->regs[0x03] = 0x60; + dev->regs[0x04] = dev->regs[0x23]; /* appears to mirror IN3 */ + dev->regs[0x05] = dev->regs[0x22]; /* appears to mirror IN2 */ + dev->regs[0x07] = 0xcd; + /* 0x08 appears to mirror IN3 Low Limit */ + dev->regs[0x09] = dev->regs[0x0f] = dev->regs[0x11] = 0xf8; /* three instances of */ + dev->regs[0x0a] = dev->regs[0x10] = dev->regs[0x12] = 0xa5; /* the same word */ + dev->regs[0x0b] = 0xac; + dev->regs[0x0c] = 0x8c; + dev->regs[0x0d] = 0x68; + dev->regs[0x0e] = 0x54; + + dev->regs[0x53] = dev->regs[0x54] = dev->regs[0x55] = 0xff; + dev->regs[0x58] = 0x31; + dev->regs[0x59] = dev->regs[0x5a] = 0x8f; + dev->regs[0x5c] = 0xe0; + dev->regs[0x5d] = 0x48; + dev->regs[0x5e] = 0xe2; + dev->regs[0x5f] = 0x3f; + } else { + dev->regs[0x58] = 0x10; + } + + /* WARNING: Array elements are register - 0x50. */ + uint16_t temp; + temp = LM78_TEMP_TO_REG(dev->values->temperatures[1]); + dev->regs_bank1[0x0] = (temp >> 8); + dev->regs_bank1[0x1] = (temp & 0xff); + dev->regs_bank1[0x3] = 0x4b; + dev->regs_bank1[0x5] = 0x50; + temp = LM78_TEMP_TO_REG(dev->values->temperatures[2]); + dev->regs_bank2[0x0] = (temp >> 8); + dev->regs_bank2[0x1] = (temp & 0xff); + dev->regs_bank2[0x3] = 0x4b; + dev->regs_bank2[0x5] = 0x50; + } else { + dev->regs[0x49] = 0x40; + } + + lm78_remap(dev); +} + + +static void +lm78_close(void *priv) +{ + lm78_t *dev = (lm78_t *) priv; + + uint16_t isa_io = (dev->local & 0xffff); + if (isa_io) + io_removehandler(isa_io, 2, lm78_isa_read, NULL, NULL, lm78_isa_write, NULL, NULL, dev); + + free(dev); +} + + +static void * +lm78_init(const device_t *info) +{ + lm78_t *dev = (lm78_t *) malloc(sizeof(lm78_t)); + memset(dev, 0, sizeof(lm78_t)); + + dev->local = info->local; + dev->values = hwm_get_values(); + lm78_reset(dev, 0); + + uint16_t isa_io = (dev->local & 0xffff); + if (isa_io) + io_sethandler(isa_io, 2, lm78_isa_read, NULL, NULL, lm78_isa_write, NULL, NULL, dev); + + return dev; +} + + +/* National Semiconductor LM78 on ISA and SMBus. */ +const device_t lm78_device = { + "National Semiconductor LM78 Hardware Monitor", + DEVICE_ISA, + 0x295 | LM78_SMBUS, + lm78_init, lm78_close, NULL, + NULL, NULL, NULL, + NULL +}; + + +/* Winbond W83781D (or ASUS AS97127F) on ISA and SMBus. */ +const device_t w83781d_device = { + "Winbond W83781D Hardware Monitor", + DEVICE_ISA, + 0x295 | LM78_SMBUS | LM78_W83781D, + lm78_init, lm78_close, NULL, + NULL, NULL, NULL, + NULL +}; + + +/* The ASUS AS99127F is a customized W83781D with no ISA interface (SMBus only), + added proprietary registers and different chip/vendor IDs. */ +const device_t as99127f_device = { + "ASUS AS99127F Rev. 1 Hardware Monitor", + DEVICE_ISA, + LM78_SMBUS | LM78_AS99127F_REV1, + lm78_init, lm78_close, NULL, + NULL, NULL, NULL, + NULL +}; + + +/* Rev. 2 changes the vendor ID back to Winbond's and brings some other changes. */ +const device_t as99127f_rev2_device = { + "ASUS AS99127F Rev. 2 Hardware Monitor", + DEVICE_AT, + LM78_SMBUS | LM78_AS99127F_REV2, + lm78_init, lm78_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/hwm_w83781d.c b/src/hwm_w83781d.c deleted file mode 100644 index 6dee12654..000000000 --- a/src/hwm_w83781d.c +++ /dev/null @@ -1,561 +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. - * - * Emulation of the Winbond W83781D hardware monitoring chip. - * - * - * - * Author: RichardG, - * Copyright 2020 RichardG. - */ -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/io.h> -#include <86box/smbus.h> -#include <86box/hwm.h> - - -#define W83781D_SMBUS 0x10000 -#define W83781D_AS99127F_REV1 0x20000 -#define W83781D_AS99127F_REV2 0x40000 -#define W83781D_AS99127F 0x60000 /* special mask covering both _REV1 and _REV2 */ -#define W83781D_VENDOR_ID ((dev->local & W83781D_AS99127F_REV1) ? 0x12C3 : 0x5CA3) - -#define CLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a))) -#define W83781D_RPM_TO_REG(r, d) CLAMP(1350000 / (r * d), 1, 255) -#define W83781D_TEMP_TO_REG(t) ((t) << 8) -#define W83781D_VOLTAGE_TO_REG(v) ((v) >> 4) - - -typedef struct { - uint32_t local; - hwm_values_t* values; - - uint8_t regs[256]; - uint8_t regs_bank1[7]; - uint8_t regs_bank2[7]; - uint8_t addr_register; - uint8_t data_register; - - uint8_t smbus_addr_main; - uint8_t smbus_addr_temp2; - uint8_t smbus_addr_temp3; - uint8_t hbacs; - uint8_t active_bank; -} w83781d_t; - - -static uint8_t w83781d_isa_read(uint16_t port, void *priv); -static uint8_t w83781d_smbus_read_byte(uint8_t addr, void *priv); -static uint8_t w83781d_smbus_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv); -static uint16_t w83781d_smbus_read_word_cmd(uint8_t addr, uint8_t cmd, void *priv); -static uint8_t w83781d_read(w83781d_t *dev, uint8_t reg, uint8_t bank); -static void w83781d_isa_write(uint16_t port, uint8_t val, void *priv); -static void w83781d_smbus_write_byte(uint8_t addr, uint8_t val, void *priv); -static void w83781d_smbus_write_byte_cmd(uint8_t addr, uint8_t cmd, uint8_t val, void *priv); -static void w83781d_smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val, void *priv); -static uint8_t w83781d_write(w83781d_t *dev, uint8_t reg, uint8_t val, uint8_t bank); -static void w83781d_reset(w83781d_t *dev, uint8_t initialization); - - -#ifdef ENABLE_W83781D_LOG -int w83781d_do_log = ENABLE_W83781D_LOG; - - -static void -w83781d_log(const char *fmt, ...) -{ - va_list ap; - - if (w83781d_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -#define w83781d_log(fmt, ...) -#endif - - -static void -w83781d_remap(w83781d_t *dev) -{ - if (!(dev->local & W83781D_SMBUS)) return; - - smbus_removehandler(0x00, 0x80, - w83781d_smbus_read_byte, w83781d_smbus_read_byte_cmd, w83781d_smbus_read_word_cmd, NULL, - w83781d_smbus_write_byte, w83781d_smbus_write_byte_cmd, w83781d_smbus_write_word_cmd, NULL, - dev); - - if (dev->smbus_addr_main) smbus_sethandler(dev->smbus_addr_main, 1, - w83781d_smbus_read_byte, w83781d_smbus_read_byte_cmd, w83781d_smbus_read_word_cmd, NULL, - w83781d_smbus_write_byte, w83781d_smbus_write_byte_cmd, w83781d_smbus_write_word_cmd, NULL, - dev); - - if (dev->smbus_addr_temp2) smbus_sethandler(dev->smbus_addr_temp2, 1, - w83781d_smbus_read_byte, w83781d_smbus_read_byte_cmd, w83781d_smbus_read_word_cmd, NULL, - w83781d_smbus_write_byte, w83781d_smbus_write_byte_cmd, w83781d_smbus_write_word_cmd, NULL, - dev); - - if (dev->smbus_addr_temp3) smbus_sethandler(dev->smbus_addr_temp3, 1, - w83781d_smbus_read_byte, w83781d_smbus_read_byte_cmd, w83781d_smbus_read_word_cmd, NULL, - w83781d_smbus_write_byte, w83781d_smbus_write_byte_cmd, w83781d_smbus_write_word_cmd, NULL, - dev); -} - - -static uint8_t -w83781d_isa_read(uint16_t port, void *priv) -{ - w83781d_t *dev = (w83781d_t *) priv; - uint8_t ret = 0xFF; - - switch (port - (dev->local & 0xFFFF)) { - case 0x0: - ret = dev->addr_register & 0x7F; - break; - case 0x1: - ret = w83781d_read(dev, dev->addr_register, dev->active_bank); - - if (dev->active_bank == 0 && - (dev->addr_register == 0x41 || dev->addr_register == 0x43 || dev->addr_register == 0x45 || dev->addr_register == 0x56 || - (dev->addr_register >= 0x60 && dev->addr_register < 0x7F))) { - /* auto-increment registers */ - dev->addr_register++; - } - break; - } - - return ret; -} - - -static uint8_t -w83781d_smbus_read_byte(uint8_t addr, void *priv) -{ - w83781d_t *dev = (w83781d_t *) priv; - - return w83781d_read(dev, dev->addr_register, 0); -} - - -static uint8_t -w83781d_smbus_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv) -{ - w83781d_t *dev = (w83781d_t *) priv; - - return w83781d_read(dev, cmd, 0); -} - - -static uint16_t -w83781d_smbus_read_word_cmd(uint8_t addr, uint8_t cmd, void *priv) -{ - w83781d_t *dev = (w83781d_t *) priv; - uint8_t rethi = 0; - uint8_t retlo = 0; - uint8_t bank = 0; - - if (addr == dev->smbus_addr_temp2 || addr == dev->smbus_addr_temp3) { - if (addr == dev->smbus_addr_temp2) - bank = 2; - else - bank = 3; - - switch (cmd & 0x3) { - case 0x0: /* temperature */ - rethi = w83781d_read(dev, 0x50, bank); - retlo = w83781d_read(dev, 0x51, bank); - break; - case 0x1: /* configuration */ - rethi = retlo = w83781d_read(dev, 0x52, bank); - break; - case 0x2: /* Thyst */ - rethi = w83781d_read(dev, 0x53, bank); - retlo = w83781d_read(dev, 0x54, bank); - break; - case 0x3: /* Tos */ - rethi = w83781d_read(dev, 0x55, bank); - retlo = w83781d_read(dev, 0x56, bank); - break; - } - } else { - rethi = retlo = w83781d_read(dev, cmd, bank); - } - - return (retlo << 8) | rethi; /* byte-swapped for some reason */ -} - - -static uint8_t -w83781d_read(w83781d_t *dev, uint8_t reg, uint8_t bank) -{ - uint8_t ret = 0; - - if ((reg >> 4) == 0x5 && bank != 0) { - /* bank-switched temperature registers */ - if (bank == 1) - ret = dev->regs_bank1[reg - 0x50]; - else - ret = dev->regs_bank2[reg - 0x50]; - } else { - /* regular registers */ - if (reg == 0x4F) /* special case for two-byte vendor ID register */ - ret = dev->hbacs ? (W83781D_VENDOR_ID >> 8) : (W83781D_VENDOR_ID & 0xFF); - else if (reg >= 0x60 && reg <= 0x7F) /* read auto-increment value RAM registers from their non-auto-increment locations */ - ret = dev->regs[reg - 0x40]; - else if (reg >= 0x80 && reg <= 0x92) /* AS99127F mirrors 00-12 to 80-92 */ - ret = dev->regs[reg - 0x80]; - else - ret = dev->regs[reg]; - } - - w83781d_log("w83781d_read(%02x, %d) = %02x\n", reg, bank, ret); - - return ret; -} - - -static void -w83781d_isa_write(uint16_t port, uint8_t val, void *priv) -{ - w83781d_t *dev = (w83781d_t *) priv; - - switch (port - (dev->local & 0xFFFF)) { - case 0x0: - dev->addr_register = val & 0x7F; - break; - case 0x1: - w83781d_write(dev, dev->addr_register, val, dev->active_bank); - - if (dev->active_bank == 0 && - (dev->addr_register == 0x41 || dev->addr_register == 0x43 || dev->addr_register == 0x45 || dev->addr_register == 0x56 || - (dev->addr_register >= 0x60 && dev->addr_register < 0x7F))) { - /* auto-increment registers */ - dev->addr_register++; - } - break; - } -} - - -static void -w83781d_smbus_write_byte(uint8_t addr, uint8_t val, void *priv) -{ - w83781d_t *dev = (w83781d_t *) priv; - - dev->addr_register = val; -} - - -static void -w83781d_smbus_write_byte_cmd(uint8_t addr, uint8_t cmd, uint8_t val, void *priv) -{ - w83781d_t *dev = (w83781d_t *) priv; - - w83781d_write(dev, cmd, val, 0); -} - - -static void -w83781d_smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val, void *priv) -{ - w83781d_t *dev = (w83781d_t *) priv; - uint8_t valhi = (val >> 8); - uint8_t vallo = (val & 0xFF); - uint8_t bank = 0; - - if (addr == dev->smbus_addr_temp2 || addr == dev->smbus_addr_temp3) { - if (addr == dev->smbus_addr_temp2) - bank = 2; - else - bank = 3; - - switch (cmd & 0x3) { - case 0x0: /* temperature */ - w83781d_write(dev, 0x50, valhi, bank); - w83781d_write(dev, 0x51, vallo, bank); - break; - case 0x1: /* configuration */ - w83781d_write(dev, 0x52, vallo, bank); - break; - case 0x2: /* Thyst */ - w83781d_write(dev, 0x53, valhi, bank); - w83781d_write(dev, 0x54, vallo, bank); - break; - case 0x3: /* Tos */ - w83781d_write(dev, 0x55, valhi, bank); - w83781d_write(dev, 0x56, vallo, bank); - break; - break; - } - return; - } - - w83781d_write(dev, cmd, vallo, bank); -} - - -static uint8_t -w83781d_write(w83781d_t *dev, uint8_t reg, uint8_t val, uint8_t bank) -{ - uint8_t remap = 0; - - if ((reg >> 4) == 0x5 && bank != 0) { - /* bank-switched temperature registers */ - switch (reg) { - case 0x50: case 0x51: - /* read-only registers */ - return 0; - } - - if (bank == 1) - dev->regs_bank1[reg - 0x50] = val; - else - dev->regs_bank2[reg - 0x50] = val; - - return 1; - } - - /* regular registers */ - switch (reg) { - case 0x41: case 0x42: case 0x4F: case 0x58: - case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29: case 0x2A: - case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: case 0x68: case 0x69: case 0x6A: - /* read-only registers */ - return 0; - } - - if (reg >= 0x60 && reg <= 0x7F) /* write auto-increment value RAM registers to their non-auto-increment locations */ - dev->regs[reg - 0x40] = val; - else if (reg >= 0x80 && reg <= 0x92) /* AS99127F mirrors 00-12 to 80-92 */ - dev->regs[reg - 0x80] = val; - else - dev->regs[reg] = val; - - switch (reg) { - case 0x40: - if (val >> 7) { - /* INITIALIZATION bit resets all registers except main SMBus address */ - w83781d_reset(dev, 1); - } - break; - case 0x47: - /* update FAN1/FAN2 values to match the new divisor */ - dev->regs[0x28] = W83781D_RPM_TO_REG(dev->values->fans[0], 1 << ((dev->regs[0x47] >> 4) & 0x3)); - dev->regs[0x29] = W83781D_RPM_TO_REG(dev->values->fans[1], 1 << ((dev->regs[0x47] >> 6) & 0x3)); - break; - case 0x48: - /* set main SMBus address */ - if (dev->local & W83781D_SMBUS) { - dev->smbus_addr_main = (dev->regs[0x48] & 0x7F); - remap = 1; - } - break; - case 0x4A: - /* set TEMP2 and TEMP3 SMBus addresses */ - if (dev->local & W83781D_SMBUS) { - /* DIS_T2 and DIS_T3 bits disable those interfaces */ - if ((dev->regs[0x4A] >> 3) & 0x1) - dev->smbus_addr_temp2 = 0x00; - else - dev->smbus_addr_temp2 = 0x48 + (dev->regs[0x4A] & 0x7); - if (dev->regs[0x4A] >> 7) - dev->smbus_addr_temp3 = 0x00; - else - dev->smbus_addr_temp3 = 0x48 + ((dev->regs[0x4A] >> 4) & 0x7); - remap = 1; - } - break; - case 0x4B: - /* update FAN3 value to match the new divisor */ - dev->regs[0x2A] = W83781D_RPM_TO_REG(dev->values->fans[2], 1 << ((dev->regs[0x4B] >> 6) & 0x3)); - break; - case 0x4E: - dev->hbacs = (dev->regs[0x4E] & 0x80); - /* FIXME: Winbond's datasheet does not specify how BANKSEL[0:2] work */ - if (dev->regs[0x4E] & 0x1) - dev->active_bank = 0; - else if (dev->regs[0x4E] & 0x2) - dev->active_bank = 1; - else if (dev->regs[0x4E] & 0x4) - dev->active_bank = 2; - break; - } - - if (remap) - w83781d_remap(dev); - - return 1; -} - - -static void -w83781d_reset(w83781d_t *dev, uint8_t initialization) -{ - memset(dev->regs, 0, 256); - memset(dev->regs + 0xC0, 0xFF, 32); /* C0-DF are 0xFF at least on the AS99127F */ - memset(dev->regs_bank1, 0, 6); - memset(dev->regs_bank2, 0, 6); - - uint8_t i; - for (i = 0; i <= 6; i++) - dev->regs[0x20 + i] = W83781D_VOLTAGE_TO_REG(dev->values->voltages[i]); - dev->regs[0x27] = dev->values->temperatures[0]; - for (i = 0; i <= 2; i++) - dev->regs[0x28 + i] = W83781D_RPM_TO_REG(dev->values->fans[i], 2); - dev->regs[0x40] = 0x01; - dev->regs[0x46] = 0x40; - dev->regs[0x47] = 0x50; - if (dev->local & W83781D_SMBUS) { - if (!initialization) /* don't reset main SMBus address if the reset was triggered by the INITIALIZATION bit */ - dev->smbus_addr_main = 0x2D; - dev->regs[0x48] = dev->smbus_addr_main; - dev->regs[0x4A] = 0x01; - dev->smbus_addr_temp2 = 0x48 + (dev->regs[0x4A] & 0x7); - dev->smbus_addr_temp3 = 0x48 + ((dev->regs[0x4A] >> 4) & 0x7); - } else { - dev->regs[0x48] = 0x00; - dev->regs[0x4A] = 0x88; - dev->smbus_addr_temp2 = dev->smbus_addr_temp3 = 0x00; - } - dev->regs[0x49] = 0x02; - dev->regs[0x4B] = 0x44; - dev->regs[0x4C] = 0x01; - dev->regs[0x4D] = 0x15; - dev->regs[0x4E] = 0x80; - dev->hbacs = (dev->regs[0x4E] & 0x80); - dev->regs[0x4F] = W83781D_VENDOR_ID >> 8; - dev->regs[0x57] = 0x80; - dev->regs[0x58] = (dev->local & W83781D_AS99127F) ? 0x31 : 0x10; - - /* - * Initialize proprietary registers on the AS99127F. The BIOS accesses some - * of these on boot through read_byte_cmd on the TEMP2 address, hanging on - * POST code C1 if they're set to 0. There's no documentation on what these - * are for. The following values were dumped from a live, initialized - * AS99127F Rev. 2 on a P4B motherboard, and they seem to work well enough. - */ - if (dev->local & W83781D_AS99127F) { - /* 0x00 appears to mirror IN2 Low Limit */ - dev->regs[0x01] = dev->regs[0x23]; /* appears to mirror IN3 */ - dev->regs[0x02] = W83781D_VOLTAGE_TO_REG(2800); /* appears to be a "maximum VCORE" of some kind; mirrors VCORE on the P4 board, but the P3 boards require this to read 2.8V */ - dev->regs[0x03] = 0x60; - dev->regs[0x04] = dev->regs[0x23]; /* appears to mirror IN3 */ - dev->regs[0x05] = dev->regs[0x22]; /* appears to mirror IN2 */ - dev->regs[0x07] = 0xCD; - /* 0x08 appears to mirror IN3 Low Limit */ - dev->regs[0x09] = dev->regs[0x0F] = dev->regs[0x11] = 0xF8; /* three instances of */ - dev->regs[0x0A] = dev->regs[0x10] = dev->regs[0x12] = 0xA5; /* the same word */ - dev->regs[0x0B] = 0xAC; - dev->regs[0x0C] = 0x8C; - dev->regs[0x0D] = 0x68; - dev->regs[0x0E] = 0x54; - - dev->regs[0x53] = dev->regs[0x54] = dev->regs[0x55] = 0xFF; - dev->regs[0x59] = dev->regs[0x5A] = 0x8F; - dev->regs[0x5C] = 0xE0; - dev->regs[0x5D] = 0x48; - dev->regs[0x5E] = 0xE2; - dev->regs[0x5F] = 0x3F; - } - - /* WARNING: Array elements are register - 0x50. */ - uint16_t temp; - temp = W83781D_TEMP_TO_REG(dev->values->temperatures[1]); - dev->regs_bank1[0x0] = temp >> 8; - dev->regs_bank1[0x1] = temp & 0xFF; - dev->regs_bank1[0x3] = 0x4B; - dev->regs_bank1[0x5] = 0x50; - temp = W83781D_TEMP_TO_REG(dev->values->temperatures[2]); - dev->regs_bank2[0x0] = temp >> 8; - dev->regs_bank2[0x1] = temp & 0xFF; - dev->regs_bank2[0x3] = 0x4B; - dev->regs_bank2[0x5] = 0x50; - - w83781d_remap(dev); -} - - -static void -w83781d_close(void *priv) -{ - w83781d_t *dev = (w83781d_t *) priv; - - uint16_t isa_io = dev->local & 0xFFFF; - if (isa_io) - io_removehandler(isa_io, 2, w83781d_isa_read, NULL, NULL, w83781d_isa_write, NULL, NULL, dev); - - free(dev); -} - - -static void * -w83781d_init(const device_t *info) -{ - w83781d_t *dev = (w83781d_t *) malloc(sizeof(w83781d_t)); - memset(dev, 0, sizeof(w83781d_t)); - - dev->local = info->local; - dev->values = hwm_get_values(); - w83781d_reset(dev, 0); - - uint16_t isa_io = dev->local & 0xFFFF; - if (isa_io) - io_sethandler(isa_io, 2, w83781d_isa_read, NULL, NULL, w83781d_isa_write, NULL, NULL, dev); - - return dev; -} - - -/* - * Standard Winbond W83781D (or ASUS AS97127F) on ISA and SMBus. - */ -const device_t w83781d_device = { - "Winbond W83781D Hardware Monitor", - DEVICE_ISA, - 0x295 | W83781D_SMBUS, - w83781d_init, w83781d_close, NULL, - NULL, NULL, NULL, - NULL -}; - - -/* - * The ASUS AS99127F is a customized W83781D with no ISA interface (SMBus only), - * added proprietary registers and different chip/vendor IDs. - */ -const device_t as99127f_device = { - "ASUS AS99127F Rev. 1 Hardware Monitor", - DEVICE_ISA, - W83781D_SMBUS | W83781D_AS99127F_REV1, - w83781d_init, w83781d_close, NULL, - NULL, NULL, NULL, - NULL -}; - - -/* - * Rev. 2 changes the vendor ID back to Winbond's and brings some other changes. - */ -const device_t as99127f_rev2_device = { - "ASUS AS99127F Rev. 2 Hardware Monitor", - DEVICE_AT, - W83781D_SMBUS | W83781D_AS99127F_REV2, - w83781d_init, w83781d_close, NULL, - NULL, NULL, NULL, - NULL -}; diff --git a/src/include/86box/hwm.h b/src/include/86box/hwm.h index f4cace10d..efde01767 100644 --- a/src/include/86box/hwm.h +++ b/src/include/86box/hwm.h @@ -11,6 +11,7 @@ * * * Author: RichardG, + * * Copyright 2020 RichardG. */ #ifndef EMU_HWM_H @@ -31,8 +32,10 @@ extern void hwm_set_values(hwm_values_t new_values); extern hwm_values_t* hwm_get_values(); +extern const device_t lm78_device; extern const device_t w83781d_device; extern const device_t as99127f_device; +extern const device_t as99127f_rev2_device; #endif /*EMU_HWM_H*/ diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index e7051e244..9ef6f013f 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -535,7 +535,7 @@ MCHOBJ := machine.o machine_table.o \ m_at_socket4_5.o m_at_socket7_s7.o m_at_super7_ss7.o \ m_at_socket8.o m_at_slot1.o m_at_slot2.o m_at_socket370.o -DEVOBJ := bugger.o hwm.o hwm_w83781d.o ibm_5161.o isamem.o isartc.o lpt.o postcard.o $(SERIAL) \ +DEVOBJ := bugger.o hwm.o hwm_lm78.o ibm_5161.o isamem.o isartc.o lpt.o postcard.o $(SERIAL) \ sio_detect.o sio_acc3221.o \ sio_f82c710.o \ sio_fdc37c66x.o sio_fdc37c669.o \ diff --git a/src/win/Makefile_ndr.mingw b/src/win/Makefile_ndr.mingw index d501f1b82..f454ce035 100644 --- a/src/win/Makefile_ndr.mingw +++ b/src/win/Makefile_ndr.mingw @@ -539,7 +539,7 @@ MCHOBJ := machine.o machine_table.o \ m_at_socket4_5.o m_at_socket7_s7.o m_at_super7_ss7.o \ m_at_socket8.o m_at_slot1.o m_at_slot2.o m_at_socket370.o -DEVOBJ := bugger.o hwm.o hwm_w83781d.o ibm_5161.o isamem.o isartc.o lpt.o postcard.o $(SERIAL) \ +DEVOBJ := bugger.o hwm.o hwm_lm78.o ibm_5161.o isamem.o isartc.o lpt.o postcard.o $(SERIAL) \ sio_acc3221.o \ sio_f82c710.o \ sio_fdc37c66x.o sio_fdc37c669.o \ From 2615f3fc48ebc5a10eed33237a8b57ef4b760f56 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 18 May 2020 00:13:12 -0300 Subject: [PATCH 07/12] Disable SPD logging --- src/spd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spd.c b/src/spd.c index da75403fb..4b63c6d2c 100644 --- a/src/spd.c +++ b/src/spd.c @@ -39,7 +39,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 1507fb767a372d02c88df0f9efd8bbf159f11ac9 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 18 May 2020 00:32:26 -0300 Subject: [PATCH 08/12] Another tiny machine table fix --- 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 16f7b71f9..f9f4c5dce 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -320,7 +320,7 @@ const machine_t machines[] = { /* PGA370 machines */ /* 440LX */ #if defined(DEV_BRANCH) && defined(NO_SIO) - { "[Socket 370 LX] Supermicro S370SLM", "s370slm", {{"Intel", cpus_Celeron}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_s370slm_init, NULL }, + { "[Socket 370 LX] Supermicro SUPER 370SLM","s370slm", {{"Intel", cpus_Celeron}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_s370slm_init, NULL }, #endif /* 440BX */ { "[Socket 370 BX] ASUS CUBX", "cubx", {{"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 }, From 928c494e6c41e756e888d1a18d64ee7c64f79ac2 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 18 May 2020 22:47:50 -0300 Subject: [PATCH 09/12] Fix SMBus logging, enabling logging should no longer return bad values. --- src/smbus.c | 46 ++++++++++++++++------------------------------ 1 file changed, 16 insertions(+), 30 deletions(-) diff --git a/src/smbus.c b/src/smbus.c index fdb98ea78..d86b167c1 100644 --- a/src/smbus.c +++ b/src/smbus.c @@ -69,18 +69,6 @@ smbus_log(const char *fmt, ...) #endif -#ifdef ENABLE_SMBUS_LOG -static uint8_t smbus_null_read_byte(uint8_t addr, void *priv) { smbus_log("SMBus: read_byte(%02x)\n", addr); return(0xff); } -static uint8_t smbus_null_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv) { smbus_log("SMBus: read_byte_cmd(%02x, %02x)\n", addr, cmd); return(0xff); } -static uint16_t smbus_null_read_word_cmd(uint8_t addr, uint8_t cmd, void *priv) { smbus_log("SMBus: read_word_cmd(%02x, %02x)\n", addr, cmd); return(0xffff); } -static uint8_t smbus_null_read_block_cmd(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len, void *priv) { smbus_log("SMBus: read_block_cmd(%02x, %02x)\n", addr, cmd); return(0x00); }; -static void smbus_null_write_byte(uint8_t addr, uint8_t val, void *priv) { smbus_log("SMBus: write_byte(%02x, %02x)\n", addr, val); } -static void smbus_null_write_byte_cmd(uint8_t addr, uint8_t cmd, uint8_t val, void *priv) { smbus_log("SMBus: write_byte_cmd(%02x, %02x, %02x)\n", addr, cmd, val); } -static void smbus_null_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val, void *priv) { smbus_log("SMBus: write_word_cmd(%02x, %02x, %04x)\n", addr, cmd, val); } -static void smbus_null_write_block_cmd(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len, void *priv) { smbus_log("SMBus: write_block_cmd(%02x, %02x, %02x)\n", addr, cmd, len); } -#endif - - void smbus_init(void) { @@ -106,26 +94,8 @@ smbus_init(void) p = NULL; } -#ifdef ENABLE_SMBUS_LOG - /* smbus[c] should be the only handler, pointing at the NULL catch handler. */ - p = (smbus_t *) malloc(sizeof(smbus_t)); - memset(p, 0, sizeof(smbus_t)); - smbus[c] = smbus_last[c] = p; - p->next = NULL; - p->prev = NULL; - p->read_byte = smbus_null_read_byte; - p->read_byte_cmd = smbus_null_read_byte_cmd; - p->read_word_cmd = smbus_null_read_word_cmd; - p->read_block_cmd = smbus_null_read_block_cmd; - p->write_byte = smbus_null_write_byte; - p->write_byte_cmd = smbus_null_write_byte_cmd; - p->write_word_cmd = smbus_null_write_word_cmd; - p->write_block_cmd = smbus_null_write_block_cmd; - p->priv = NULL; -#else /* smbus[c] should be NULL. */ smbus[c] = smbus_last[c] = NULL; -#endif } } @@ -262,6 +232,8 @@ smbus_read_byte(uint8_t addr) } } + smbus_log("SMBus: read_byte(%02X) = %02X\n", addr, ret); + return(ret); } @@ -283,6 +255,8 @@ smbus_read_byte_cmd(uint8_t addr, uint8_t cmd) } } + smbus_log("SMBus: read_byte_cmd(%02X, %02X) = %02X\n", addr, cmd, ret); + return(ret); } @@ -304,6 +278,8 @@ smbus_read_word_cmd(uint8_t addr, uint8_t cmd) } } + smbus_log("SMBus: read_word_cmd(%02X, %02X) = %04X\n", addr, cmd, ret); + return(ret); } @@ -325,6 +301,8 @@ smbus_read_block_cmd(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len) } } + smbus_log("SMBus: read_block_cmd(%02X, %02X) = %02X\n", addr, cmd, len); + return(ret); } @@ -346,6 +324,8 @@ smbus_write_byte(uint8_t addr, uint8_t val) } } + smbus_log("SMBus: write_byte(%02X, %02X)\n", addr, val); + return; } @@ -366,6 +346,8 @@ smbus_write_byte_cmd(uint8_t addr, uint8_t cmd, uint8_t val) } } + smbus_log("SMBus: write_byte_cmd(%02X, %02X, %02X)\n", addr, cmd, val); + return; } @@ -386,6 +368,8 @@ smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val) } } + smbus_log("SMBus: write_word_cmd(%02X, %02X, %04X)\n", addr, cmd, val); + return; } @@ -406,5 +390,7 @@ smbus_write_block_cmd(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len) } } + smbus_log("SMBus: write_block_cmd(%02X, %02X, %02X)\n", addr, cmd, len); + return; } From 2ff06457d5979eca91e3f8d5587688825207b0ae Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 18 May 2020 22:54:59 -0300 Subject: [PATCH 10/12] Hardware monitor refactoring, part 2 --- src/hwm.c | 1 + src/hwm_lm75.c | 269 ++++++++++++++++++++++++++++++++++ src/hwm_lm78.c | 261 +++++++++++---------------------- src/include/86box/hwm.h | 19 +++ src/machine/m_at_slot1.c | 2 +- src/machine/m_at_socket370.c | 2 +- src/machine/m_at_socket7_s7.c | 4 +- src/win/Makefile.mingw | 2 +- src/win/Makefile_ndr.mingw | 2 +- 9 files changed, 382 insertions(+), 180 deletions(-) create mode 100644 src/hwm_lm75.c diff --git a/src/hwm.c b/src/hwm.c index cac194d98..7ef55b3ef 100644 --- a/src/hwm.c +++ b/src/hwm.c @@ -11,6 +11,7 @@ * * * Author: RichardG, + * * Copyright 2020 RichardG. */ diff --git a/src/hwm_lm75.c b/src/hwm_lm75.c new file mode 100644 index 000000000..1b6431395 --- /dev/null +++ b/src/hwm_lm75.c @@ -0,0 +1,269 @@ +/* + * 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. + * + * Emulation of the National Semiconductor LM75 temperature sensor chip. + * + * + * + * Author: RichardG, + * + * Copyright 2020 RichardG. + */ +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/smbus.h> +#include <86box/hwm.h> + + +#define LM75_TEMP_TO_REG(t) ((t) << 8) + + +static uint8_t lm75_smbus_read_byte(uint8_t addr, void *priv); +static uint8_t lm75_smbus_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv); +static uint16_t lm75_smbus_read_word_cmd(uint8_t addr, uint8_t cmd, void *priv); +static void lm75_smbus_write_byte(uint8_t addr, uint8_t val, void *priv); +static void lm75_smbus_write_byte_cmd(uint8_t addr, uint8_t cmd, uint8_t val, void *priv); +static void lm75_smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val, void *priv); +static void lm75_reset(lm75_t *dev); + + +#ifdef ENABLE_LM75_LOG +int lm75_do_log = ENABLE_LM75_LOG; + + +static void +lm75_log(const char *fmt, ...) +{ + va_list ap; + + if (lm75_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define lm75_log(fmt, ...) +#endif + + +void +lm75_remap(lm75_t *dev) +{ + lm75_log("LM75: remapping to SMBus %02Xh\n", dev->smbus_addr); + + smbus_removehandler(dev->smbus_addr, 1, + lm75_smbus_read_byte, lm75_smbus_read_byte_cmd, lm75_smbus_read_word_cmd, NULL, + lm75_smbus_write_byte, lm75_smbus_write_byte_cmd, lm75_smbus_write_word_cmd, NULL, + dev); + + if (dev->smbus_addr) smbus_sethandler(dev->smbus_addr, 1, + lm75_smbus_read_byte, lm75_smbus_read_byte_cmd, lm75_smbus_read_word_cmd, NULL, + lm75_smbus_write_byte, lm75_smbus_write_byte_cmd, lm75_smbus_write_word_cmd, NULL, + dev); +} + + +static uint8_t +lm75_smbus_read_byte(uint8_t addr, void *priv) +{ + lm75_t *dev = (lm75_t *) priv; + return lm75_read(dev, dev->addr_register); +} + + +static uint8_t +lm75_smbus_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv) +{ + lm75_t *dev = (lm75_t *) priv; + return lm75_read(dev, cmd); +} + +static uint16_t +lm75_smbus_read_word_cmd(uint8_t addr, uint8_t cmd, void *priv) +{ + lm75_t *dev = (lm75_t *) priv; + uint8_t rethi = 0; + uint8_t retlo = 0; + + switch (cmd & 0x3) { + case 0x0: /* temperature */ + rethi = lm75_read(dev, 0x0); + retlo = lm75_read(dev, 0x1); + break; + case 0x1: /* configuration */ + rethi = retlo = lm75_read(dev, 0x2); + break; + case 0x2: /* Thyst */ + rethi = lm75_read(dev, 0x3); + retlo = lm75_read(dev, 0x4); + break; + case 0x3: /* Tos */ + rethi = lm75_read(dev, 0x5); + retlo = lm75_read(dev, 0x6); + break; + } + + return (retlo << 8) | rethi; /* byte-swapped for some reason */ +} + + +uint8_t +lm75_read(lm75_t *dev, uint8_t reg) +{ + uint8_t ret; + + /* The AS99127F hardware monitor uses the addresses of its LM75 devices + to access some of its proprietary registers. Pass this operation on to + the main monitor address through an internal SMBus call, if necessary. */ + if ((reg >= 0x80) && (dev->as99127f_smbus_addr)) + ret = smbus_read_byte_cmd(dev->as99127f_smbus_addr, reg); + else + ret = dev->regs[reg & 0x7]; + + lm75_log("LM75: read(%x) = %02x\n", reg, ret); + + return ret; +} + + +static void +lm75_smbus_write_byte(uint8_t addr, uint8_t val, void *priv) +{ + lm75_t *dev = (lm75_t *) priv; + dev->addr_register = val; +} + + +static void +lm75_smbus_write_byte_cmd(uint8_t addr, uint8_t cmd, uint8_t val, void *priv) +{ + lm75_t *dev = (lm75_t *) priv; + lm75_write(dev, cmd, val); +} + + +static void +lm75_smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val, void *priv) +{ + lm75_t *dev = (lm75_t *) priv; + uint8_t valhi = (val >> 8); + uint8_t vallo = (val & 0xff); + + switch (cmd & 0x3) { + case 0x0: /* temperature */ + lm75_write(dev, 0x0, valhi); + lm75_write(dev, 0x1, vallo); + break; + case 0x1: /* configuration */ + lm75_write(dev, 0x2, vallo); + break; + case 0x2: /* Thyst */ + lm75_write(dev, 0x3, valhi); + lm75_write(dev, 0x4, vallo); + break; + case 0x3: /* Tos */ + lm75_write(dev, 0x5, valhi); + lm75_write(dev, 0x6, vallo); + break; + break; + } +} + + +uint8_t +lm75_write(lm75_t *dev, uint8_t reg, uint8_t val) +{ + lm75_log("LM75: write(%x, %02x)\n", reg, val); + + /* The AS99127F hardware monitor uses the addresses of its LM75 devices + to access some of its proprietary registers. Pass this operation on to + the main monitor address through an internal SMBus call, if necessary. */ + if ((reg >= 0x80) && (dev->as99127f_smbus_addr)) { + smbus_write_byte_cmd(dev->as99127f_smbus_addr, reg, val); + return 1; + } + + uint8_t reg_idx = (reg & 0x7); + + if ((reg_idx <= 0x1) || (reg_idx == 0x7)) + return 0; /* read-only registers */ + + dev->regs[reg_idx] = val; + + return 1; +} + + +static void +lm75_reset(lm75_t *dev) +{ + uint16_t temp = LM75_TEMP_TO_REG(dev->values->temperatures[dev->local >> 8]); + dev->regs[0x0] = (temp >> 8); + dev->regs[0x1] = temp; + dev->regs[0x3] = 0x4b; + dev->regs[0x5] = 0x50; + + lm75_remap(dev); +} + + +static void +lm75_close(void *priv) +{ + lm75_t *dev = (lm75_t *) priv; + free(dev); +} + + +static void * +lm75_init(const device_t *info) +{ + lm75_t *dev = (lm75_t *) malloc(sizeof(lm75_t)); + memset(dev, 0, sizeof(lm75_t)); + + dev->local = info->local; + dev->values = hwm_get_values(); + + dev->smbus_addr = dev->local; + dev->as99127f_smbus_addr = 0x00; + + lm75_reset(dev); + + return dev; +} + + +/* LM75 on SMBus address 4Ah, reporting temperatures[1]. */ +const device_t lm75_1_4a_device = { + "National Semiconductor LM75 Temperature Sensor", + DEVICE_AT, + 0x14a, + lm75_init, lm75_close, NULL, + NULL, NULL, NULL, + NULL +}; + + +/* LM75 secondary/tertiary temperature sensors built into + the Winbond W83781D family. Not to be used stand-alone. */ +const device_t lm75_w83781d_device = { + "Winbond W83781D Secondary Temperature Sensor", + DEVICE_AT, + 0, + lm75_init, lm75_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/hwm_lm78.c b/src/hwm_lm78.c index 27c15fe8f..2ecc36f14 100644 --- a/src/hwm_lm78.c +++ b/src/hwm_lm78.c @@ -39,23 +39,19 @@ #define CLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a))) #define LM78_RPM_TO_REG(r, d) ((r) ? CLAMP(1350000 / (r * d), 1, 255) : 0) -#define LM78_TEMP_TO_REG(t) ((t) << 8) #define LM78_VOLTAGE_TO_REG(v) ((v) >> 4) typedef struct { uint32_t local; - hwm_values_t* values; + hwm_values_t *values; + device_t *lm75[2]; uint8_t regs[256]; - uint8_t regs_bank1[7]; - uint8_t regs_bank2[7]; uint8_t addr_register; uint8_t data_register; - uint8_t smbus_addr_main; - uint8_t smbus_addr_temp2; - uint8_t smbus_addr_temp3; + uint8_t smbus_addr; uint8_t hbacs; uint8_t active_bank; } lm78_t; @@ -97,29 +93,31 @@ lm78_log(const char *fmt, ...) static void lm78_remap(lm78_t *dev) { + lm75_t *lm75; + if (!(dev->local & LM78_SMBUS)) return; - lm78_log("LM78: SMBus remap: main = %02Xh; temp2 = %02Xh; temp3 = %02Xh\n", dev->smbus_addr_main, dev->smbus_addr_temp2, dev->smbus_addr_temp3); + lm78_log("LM78: remapping to SMBus %02Xh\n", dev->smbus_addr); - smbus_removehandler(0x00, 0x80, + smbus_removehandler(dev->smbus_addr, 1, lm78_smbus_read_byte, lm78_smbus_read_byte_cmd, lm78_smbus_read_word_cmd, NULL, lm78_smbus_write_byte, lm78_smbus_write_byte_cmd, lm78_smbus_write_word_cmd, NULL, dev); - if (dev->smbus_addr_main) smbus_sethandler(dev->smbus_addr_main, 1, + if (dev->smbus_addr) smbus_sethandler(dev->smbus_addr, 1, lm78_smbus_read_byte, lm78_smbus_read_byte_cmd, lm78_smbus_read_word_cmd, NULL, lm78_smbus_write_byte, lm78_smbus_write_byte_cmd, lm78_smbus_write_word_cmd, NULL, dev); - if (dev->smbus_addr_temp2) smbus_sethandler(dev->smbus_addr_temp2, 1, - lm78_smbus_read_byte, lm78_smbus_read_byte_cmd, lm78_smbus_read_word_cmd, NULL, - lm78_smbus_write_byte, lm78_smbus_write_byte_cmd, lm78_smbus_write_word_cmd, NULL, - dev); - - if (dev->smbus_addr_temp3) smbus_sethandler(dev->smbus_addr_temp3, 1, - lm78_smbus_read_byte, lm78_smbus_read_byte_cmd, lm78_smbus_read_word_cmd, NULL, - lm78_smbus_write_byte, lm78_smbus_write_byte_cmd, lm78_smbus_write_word_cmd, NULL, - dev); + if (dev->local & LM78_AS99127F) { + /* Store the main SMBus address on the LM75 devices to ensure reads/writes + to the AS99127F's proprietary registers are passed through to this side. */ + for (uint8_t i = 0; i <= 1; i++) { + lm75 = device_get_priv(dev->lm75[i]); + if (lm75) + lm75->as99127f_smbus_addr = dev->smbus_addr; + } + } } @@ -127,9 +125,9 @@ static uint8_t lm78_isa_read(uint16_t port, void *priv) { lm78_t *dev = (lm78_t *) priv; - uint8_t ret = 0xFF; + uint8_t ret = 0xff; - switch (port & 0xf) { + switch (port & 0x7) { case 0x5: ret = (dev->addr_register & 0x7f); break; @@ -143,6 +141,9 @@ lm78_isa_read(uint16_t port, void *priv) dev->addr_register++; } break; + default: + lm78_log("LM78: Read from unknown ISA port %x\n", port & 0x7); + break; } return ret; @@ -153,7 +154,7 @@ static uint8_t lm78_smbus_read_byte(uint8_t addr, void *priv) { lm78_t *dev = (lm78_t *) priv; - return lm78_smbus_read_byte_cmd(addr, dev->addr_register, priv); + return lm78_read(dev, dev->addr_register, dev->active_bank); } @@ -161,14 +162,7 @@ static uint8_t lm78_smbus_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv) { lm78_t *dev = (lm78_t *) priv; - - uint8_t bank = 0; - if (addr == dev->smbus_addr_temp2) - bank = 1; - else if (addr == dev->smbus_addr_temp3) - bank = 2; - - return lm78_read(dev, cmd, bank); + return lm78_read(dev, cmd, dev->active_bank); } @@ -176,38 +170,7 @@ static uint16_t lm78_smbus_read_word_cmd(uint8_t addr, uint8_t cmd, void *priv) { lm78_t *dev = (lm78_t *) priv; - uint8_t rethi = 0; - uint8_t retlo = 0; - uint8_t bank = 0; - - if ((dev->local & LM78_WINBOND) && ((addr == dev->smbus_addr_temp2) || (addr == dev->smbus_addr_temp3))) { - if (addr == dev->smbus_addr_temp2) - bank = 2; - else - bank = 3; - - switch (cmd & 0x3) { - case 0x0: /* temperature */ - rethi = lm78_read(dev, 0x50, bank); - retlo = lm78_read(dev, 0x51, bank); - break; - case 0x1: /* configuration */ - rethi = retlo = lm78_read(dev, 0x52, bank); - break; - case 0x2: /* Thyst */ - rethi = lm78_read(dev, 0x53, bank); - retlo = lm78_read(dev, 0x54, bank); - break; - case 0x3: /* Tos */ - rethi = lm78_read(dev, 0x55, bank); - retlo = lm78_read(dev, 0x56, bank); - break; - } - } else { - rethi = retlo = lm78_read(dev, cmd, bank); - } - - return (retlo << 8) | rethi; /* byte-swapped for some reason */ + return (lm78_read(dev, cmd, dev->active_bank) << 8) | lm78_read(dev, cmd, dev->active_bank); } @@ -215,20 +178,20 @@ static uint8_t lm78_read(lm78_t *dev, uint8_t reg, uint8_t bank) { uint8_t ret = 0; + lm75_t *lm75; - if ((dev->local & LM78_WINBOND) && ((reg >> 4) == 0x5) && (bank != 0)) { - /* bank-switched temperature registers */ - if (bank == 1) - ret = dev->regs_bank1[reg & 0x7]; - else - ret = dev->regs_bank2[reg & 0x7]; + if (((reg >> 4) == 0x5) && (bank != 0)) { + /* LM75 registers */ + lm75 = device_get_priv(dev->lm75[bank - 1]); + if (lm75) + ret = lm75_read(lm75, reg & 0x7); } else { /* regular registers */ if ((reg == 0x4f) && (dev->local & LM78_WINBOND)) /* special case for two-byte vendor ID register */ ret = (dev->hbacs ? (LM78_WINBOND_VENDOR_ID >> 8) : LM78_WINBOND_VENDOR_ID); else if ((reg >= 0x60) && (reg <= 0x7f)) /* read auto-increment value RAM registers from their non-auto-increment locations */ ret = dev->regs[reg & 0x3f]; - else if ((reg >= 0x80) && (reg <= 0x92)) /* AS99127F mirrors POST RAM to 80-92 */ + else if ((reg >= 0x80) && (reg <= 0x92)) /* AS99127F mirrors [0x00:0x12] to [0x80:0x92] */ ret = dev->regs[reg - 0x7f]; else ret = dev->regs[reg]; @@ -245,7 +208,7 @@ lm78_isa_write(uint16_t port, uint8_t val, void *priv) { lm78_t *dev = (lm78_t *) priv; - switch (port & 0xf) { + switch (port & 0x7) { case 0x5: dev->addr_register = (val & 0x7f); break; @@ -259,6 +222,9 @@ lm78_isa_write(uint16_t port, uint8_t val, void *priv) dev->addr_register++; } break; + default: + lm78_log("LM78: Write %02x to unknown ISA port %x\n", val, port & 0x7); + break; } } @@ -267,7 +233,6 @@ static void lm78_smbus_write_byte(uint8_t addr, uint8_t val, void *priv) { lm78_t *dev = (lm78_t *) priv; - dev->addr_register = val; } @@ -276,8 +241,7 @@ static void lm78_smbus_write_byte_cmd(uint8_t addr, uint8_t cmd, uint8_t val, void *priv) { lm78_t *dev = (lm78_t *) priv; - - lm78_write(dev, cmd, val, 0); + lm78_write(dev, cmd, val, dev->active_bank); } @@ -285,60 +249,23 @@ static void lm78_smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val, void *priv) { lm78_t *dev = (lm78_t *) priv; - uint8_t valhi = (val >> 8); - uint8_t vallo = (val & 0xff); - uint8_t bank = 0; - - if ((dev->local & LM78_WINBOND) && ((addr == dev->smbus_addr_temp2) || (addr == dev->smbus_addr_temp3))) { - if (addr == dev->smbus_addr_temp2) - bank = 2; - else - bank = 3; - - switch (cmd & 0x3) { - case 0x0: /* temperature */ - lm78_write(dev, 0x50, valhi, bank); - lm78_write(dev, 0x51, vallo, bank); - break; - case 0x1: /* configuration */ - lm78_write(dev, 0x52, vallo, bank); - break; - case 0x2: /* Thyst */ - lm78_write(dev, 0x53, valhi, bank); - lm78_write(dev, 0x54, vallo, bank); - break; - case 0x3: /* Tos */ - lm78_write(dev, 0x55, valhi, bank); - lm78_write(dev, 0x56, vallo, bank); - break; - break; - } - return; - } - - lm78_write(dev, cmd, vallo, bank); + lm78_write(dev, cmd, val, dev->active_bank); } static uint8_t lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank) { - uint8_t remap = 0; + lm75_t *lm75; - if ((dev->local & LM78_WINBOND) && ((reg >> 4) == 0x5) && (bank != 0)) { - /* bank-switched temperature registers */ - switch (reg) { - case 0x50: case 0x51: - /* read-only registers */ - return 0; - } + lm78_log("LM78: write(%02x, %d, %02x)\n", reg, bank, val); - if (bank == 1) - dev->regs_bank1[reg & 0x7] = val; - else - dev->regs_bank2[reg & 0x7] = val; - - goto end; + if (((reg >> 4) == 0x5) && (bank != 0)) { + /* LM75 registers */ + lm75 = device_get_priv(dev->lm75[bank - 1]); + if (lm75) + lm75_write(lm75, reg & 0x7, val); + return 1; } /* regular registers */ @@ -357,7 +284,7 @@ lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank) if ((reg >= 0x60) && (reg <= 0x7f)) /* write auto-increment value RAM registers to their non-auto-increment locations */ dev->regs[reg & 0x3f] = val; - else if ((reg >= 0x80) && (reg <= 0x92)) /* AS99127F mirrors POST RAM to 80-92 */ + else if ((reg >= 0x80) && (reg <= 0x92)) /* AS99127F mirrors [0x00:0x12] to [0x80:0x92] */ dev->regs[reg & 0x7f] = val; else dev->regs[reg] = val; @@ -377,8 +304,8 @@ lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank) case 0x48: /* set main SMBus address */ if (dev->local & LM78_SMBUS) { - dev->smbus_addr_main = (dev->regs[0x48] & 0x7f); - remap = 1; + dev->smbus_addr = (dev->regs[0x48] & 0x7f); + lm78_remap(dev); } break; case 0x49: @@ -394,18 +321,16 @@ lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank) } break; case 0x4a: - /* set TEMP2 and TEMP3 SMBus addresses (Winbond only) */ + /* set LM75 SMBus addresses (Winbond only) */ if (dev->local & LM78_SMBUS) { - /* DIS_T2 and DIS_T3 bit disable those interfaces */ - if (dev->regs[0x4a] & 0x08) - dev->smbus_addr_temp2 = 0x00; - else - dev->smbus_addr_temp2 = (0x48 + (dev->regs[0x4a] & 0x7)); - if (dev->regs[0x4a] & 0x80) - dev->smbus_addr_temp3 = 0x00; - else - dev->smbus_addr_temp3 = (0x48 + ((dev->regs[0x4a] >> 4) & 0x7)); - remap = 1; + for (uint8_t i = 0; i <= 1; i++) { + lm75 = device_get_priv(dev->lm75[i]); + if (dev->regs[0x4a] & (0x08 * (0x10 * i))) /* DIS_T2 and DIS_T3 bit disable those interfaces */ + lm75->smbus_addr = 0x00; + else + lm75->smbus_addr = (0x48 + ((dev->regs[0x4a] >> (i * 4)) & 0x7)); + lm75_remap(lm75); + } } break; case 0x4b: @@ -426,12 +351,6 @@ lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank) break; } - if (remap) - lm78_remap(dev); - -end: - lm78_log("LM78: write(%02x, %d) = %02x\n", reg, bank, val); - return 1; } @@ -441,8 +360,6 @@ lm78_reset(lm78_t *dev, uint8_t initialization) { memset(dev->regs, 0, 256); memset(dev->regs + 0xc0, 0xff, 32); /* C0-DF are 0xFF at least on the AS99127F */ - memset(dev->regs_bank1, 0, 6); - memset(dev->regs_bank2, 0, 6); uint8_t i; for (i = 0; i <= 6; i++) @@ -455,20 +372,14 @@ lm78_reset(lm78_t *dev, uint8_t initialization) dev->regs[0x47] = 0x50; if (dev->local & LM78_SMBUS) { if (!initialization) /* don't reset main SMBus address if the reset was triggered by the INITIALIZATION bit */ - dev->smbus_addr_main = 0x2d; - dev->regs[0x48] = dev->smbus_addr_main; - if (dev->local & LM78_WINBOND) { + dev->smbus_addr = 0x2d; + dev->regs[0x48] = dev->smbus_addr; + if (dev->local & LM78_WINBOND) dev->regs[0x4a] = 0x01; - dev->smbus_addr_temp2 = (0x48 + (dev->regs[0x4a] & 0x7)); - dev->smbus_addr_temp3 = (0x48 + ((dev->regs[0x4a] >> 4) & 0x7)); - } else { - dev->smbus_addr_temp2 = dev->smbus_addr_temp3 = 0x00; - } } else { dev->regs[0x48] = 0x00; if (dev->local & LM78_WINBOND) dev->regs[0x4a] = 0x88; - dev->smbus_addr_temp2 = dev->smbus_addr_temp3 = 0x00; } if (dev->local & LM78_WINBOND) { dev->regs[0x49] = 0x02; @@ -480,17 +391,15 @@ lm78_reset(lm78_t *dev, uint8_t initialization) dev->regs[0x4f] = (LM78_WINBOND_VENDOR_ID >> 8); dev->regs[0x57] = 0x80; - /* - * Initialize proprietary registers on the AS99127F. The BIOS accesses some - * of these on boot through read_byte_cmd on the TEMP2 address, hanging on - * POST code C1 if they're set to 0. There's no documentation on what these - * are for. The following values were dumped from a live, initialized - * AS99127F Rev. 2 on a P4B motherboard, and they seem to work well enough. - */ + /* Initialize proprietary registers on the AS99127F. The BIOS accesses some + of these on boot through read_byte_cmd on the TEMP2 address, hanging on + POST code C1 if they're defaulted to 0. There's no documentation on what + these are for. The following values were dumped from a live, initialized + AS99127F Rev. 2 on a P4B motherboard, and they seem to work well enough. */ if (dev->local & LM78_AS99127F) { /* 0x00 appears to mirror IN2 Low Limit */ dev->regs[0x01] = dev->regs[0x23]; /* appears to mirror IN3 */ - dev->regs[0x02] = LM78_VOLTAGE_TO_REG(2800); /* appears to be a "maximum VCORE" of some kind; mirrors VCORE on the P4 board, but the P3 boards require this to read 2.8V */ + dev->regs[0x02] = LM78_VOLTAGE_TO_REG(2800); /* appears to be a "maximum VCORE" of some kind; must read 2.8V on P3 boards */ dev->regs[0x03] = 0x60; dev->regs[0x04] = dev->regs[0x23]; /* appears to mirror IN3 */ dev->regs[0x05] = dev->regs[0x22]; /* appears to mirror IN2 */ @@ -513,19 +422,6 @@ lm78_reset(lm78_t *dev, uint8_t initialization) } else { dev->regs[0x58] = 0x10; } - - /* WARNING: Array elements are register - 0x50. */ - uint16_t temp; - temp = LM78_TEMP_TO_REG(dev->values->temperatures[1]); - dev->regs_bank1[0x0] = (temp >> 8); - dev->regs_bank1[0x1] = (temp & 0xff); - dev->regs_bank1[0x3] = 0x4b; - dev->regs_bank1[0x5] = 0x50; - temp = LM78_TEMP_TO_REG(dev->values->temperatures[2]); - dev->regs_bank2[0x0] = (temp >> 8); - dev->regs_bank2[0x1] = (temp & 0xff); - dev->regs_bank2[0x3] = 0x4b; - dev->regs_bank2[0x5] = 0x50; } else { dev->regs[0x49] = 0x40; } @@ -541,7 +437,7 @@ lm78_close(void *priv) uint16_t isa_io = (dev->local & 0xffff); if (isa_io) - io_removehandler(isa_io, 2, lm78_isa_read, NULL, NULL, lm78_isa_write, NULL, NULL, dev); + io_removehandler(isa_io, 8, lm78_isa_read, NULL, NULL, lm78_isa_write, NULL, NULL, dev); free(dev); } @@ -555,11 +451,26 @@ lm78_init(const device_t *info) dev->local = info->local; dev->values = hwm_get_values(); + + /* initialize secondary/tertiary LM75 sensors on Winbond */ + for (uint8_t i = 0; i <= 1; i++) { + if (dev->local & LM78_WINBOND) { + dev->lm75[i] = (device_t *) malloc(sizeof(device_t)); + memcpy(dev->lm75[i], &lm75_w83781d_device, sizeof(device_t)); + dev->lm75[i]->local = ((i + 1) << 8); + if (dev->local & LM78_SMBUS) + dev->lm75[i]->local |= (0x48 + i); + device_add(dev->lm75[i]); + } else { + dev->lm75[i] = NULL; + } + } + lm78_reset(dev, 0); uint16_t isa_io = (dev->local & 0xffff); if (isa_io) - io_sethandler(isa_io, 2, lm78_isa_read, NULL, NULL, lm78_isa_write, NULL, NULL, dev); + io_sethandler(isa_io, 8, lm78_isa_read, NULL, NULL, lm78_isa_write, NULL, NULL, dev); return dev; } @@ -569,7 +480,7 @@ lm78_init(const device_t *info) const device_t lm78_device = { "National Semiconductor LM78 Hardware Monitor", DEVICE_ISA, - 0x295 | LM78_SMBUS, + 0x290 | LM78_SMBUS, lm78_init, lm78_close, NULL, NULL, NULL, NULL, NULL @@ -580,7 +491,7 @@ const device_t lm78_device = { const device_t w83781d_device = { "Winbond W83781D Hardware Monitor", DEVICE_ISA, - 0x295 | LM78_SMBUS | LM78_W83781D, + 0x290 | LM78_SMBUS | LM78_W83781D, lm78_init, lm78_close, NULL, NULL, NULL, NULL, NULL diff --git a/src/include/86box/hwm.h b/src/include/86box/hwm.h index efde01767..0cae77dbb 100644 --- a/src/include/86box/hwm.h +++ b/src/include/86box/hwm.h @@ -27,10 +27,29 @@ typedef struct _hwm_values_ { uint16_t voltages[8]; } hwm_values_t; +typedef struct { + uint32_t local; + hwm_values_t *values; + + uint8_t regs[8]; + uint8_t addr_register; + uint8_t temp_idx; + uint8_t smbus_addr; + + uint8_t as99127f_smbus_addr; +} lm75_t; + extern void hwm_set_values(hwm_values_t new_values); extern hwm_values_t* hwm_get_values(); +extern void lm75_remap(lm75_t *dev); +extern uint8_t lm75_read(lm75_t *dev, uint8_t reg); +extern uint8_t lm75_write(lm75_t *dev, uint8_t reg, uint8_t val); + + +extern const device_t lm75_1_4a_device; +extern const device_t lm75_w83781d_device; extern const device_t lm78_device; extern const device_t w83781d_device; diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index 65838fd21..436a522f5 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -214,7 +214,7 @@ machine_at_p3bf_init(const machine_t *model) 3000 /* Power */ }, { /* temperatures */ 30, /* MB */ - 0, /* unused */ + 30, /* JTPWR */ 30 /* CPU */ }, { /* voltages */ 2050, /* VCORE (2.05V by default) */ diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index b0c75f80a..8852ee804 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -135,7 +135,7 @@ machine_at_cubx_init(const machine_t *model) 3000 /* Power */ }, { /* temperatures */ 30, /* MB */ - 0, /* unused */ + 30, /* JTPWR */ 30 /* CPU */ }, { /* voltages */ 2050, /* VCORE (2.05V by default) */ diff --git a/src/machine/m_at_socket7_s7.c b/src/machine/m_at_socket7_s7.c index c38fecbd4..c4792518c 100644 --- a/src/machine/m_at_socket7_s7.c +++ b/src/machine/m_at_socket7_s7.c @@ -847,7 +847,8 @@ machine_at_p5mms98_init(const machine_t *model) 3000, /* CPU */ 3000 /* Chassis */ }, { /* temperatures */ - 28 /* CPU (locked at 28?) */ + 0, /* unused */ + 30 /* CPU */ }, { /* voltages */ 3300, /* VCORE (3.3V by default) */ 3300, /* VIO (3.3V) */ @@ -873,6 +874,7 @@ machine_at_p5mms98_init(const machine_t *model) } hwm_set_values(machine_hwm); device_add(&lm78_device); + device_add(&lm75_1_4a_device); return ret; } diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 9ef6f013f..9e2ad81d9 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -535,7 +535,7 @@ MCHOBJ := machine.o machine_table.o \ m_at_socket4_5.o m_at_socket7_s7.o m_at_super7_ss7.o \ m_at_socket8.o m_at_slot1.o m_at_slot2.o m_at_socket370.o -DEVOBJ := bugger.o hwm.o hwm_lm78.o ibm_5161.o isamem.o isartc.o lpt.o postcard.o $(SERIAL) \ +DEVOBJ := bugger.o hwm.o hwm_lm75.o hwm_lm78.o ibm_5161.o isamem.o isartc.o lpt.o postcard.o $(SERIAL) \ sio_detect.o sio_acc3221.o \ sio_f82c710.o \ sio_fdc37c66x.o sio_fdc37c669.o \ diff --git a/src/win/Makefile_ndr.mingw b/src/win/Makefile_ndr.mingw index f454ce035..29ff11093 100644 --- a/src/win/Makefile_ndr.mingw +++ b/src/win/Makefile_ndr.mingw @@ -539,7 +539,7 @@ MCHOBJ := machine.o machine_table.o \ m_at_socket4_5.o m_at_socket7_s7.o m_at_super7_ss7.o \ m_at_socket8.o m_at_slot1.o m_at_slot2.o m_at_socket370.o -DEVOBJ := bugger.o hwm.o hwm_lm78.o ibm_5161.o isamem.o isartc.o lpt.o postcard.o $(SERIAL) \ +DEVOBJ := bugger.o hwm.o hwm_lm75.o hwm_lm78.o ibm_5161.o isamem.o isartc.o lpt.o postcard.o $(SERIAL) \ sio_acc3221.o \ sio_f82c710.o \ sio_fdc37c66x.o sio_fdc37c669.o \ From 0eead95b5206508c655101ee353b13f3c1d33fcc Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 18 May 2020 23:00:05 -0300 Subject: [PATCH 11/12] Convert permanent log lines to uppercase hexadecimal --- src/hwm_lm75.c | 4 ++-- src/hwm_lm78.c | 10 +++++----- src/spd.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/hwm_lm75.c b/src/hwm_lm75.c index 1b6431395..0d937c194 100644 --- a/src/hwm_lm75.c +++ b/src/hwm_lm75.c @@ -133,7 +133,7 @@ lm75_read(lm75_t *dev, uint8_t reg) else ret = dev->regs[reg & 0x7]; - lm75_log("LM75: read(%x) = %02x\n", reg, ret); + lm75_log("LM75: read(%02X) = %02X\n", reg, ret); return ret; } @@ -186,7 +186,7 @@ lm75_smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val, void *priv) uint8_t lm75_write(lm75_t *dev, uint8_t reg, uint8_t val) { - lm75_log("LM75: write(%x, %02x)\n", reg, val); + lm75_log("LM75: write(%02X, %02X)\n", reg, val); /* The AS99127F hardware monitor uses the addresses of its LM75 devices to access some of its proprietary registers. Pass this operation on to diff --git a/src/hwm_lm78.c b/src/hwm_lm78.c index 2ecc36f14..2cac22881 100644 --- a/src/hwm_lm78.c +++ b/src/hwm_lm78.c @@ -142,7 +142,7 @@ lm78_isa_read(uint16_t port, void *priv) } break; default: - lm78_log("LM78: Read from unknown ISA port %x\n", port & 0x7); + lm78_log("LM78: Read from unknown ISA port %d\n", port & 0x7); break; } @@ -197,7 +197,7 @@ lm78_read(lm78_t *dev, uint8_t reg, uint8_t bank) ret = dev->regs[reg]; } - lm78_log("LM78: read(%02x, %d) = %02x\n", reg, bank, ret); + lm78_log("LM78: read(%02X, %d) = %02X\n", reg, bank, ret); return ret; } @@ -223,7 +223,7 @@ lm78_isa_write(uint16_t port, uint8_t val, void *priv) } break; default: - lm78_log("LM78: Write %02x to unknown ISA port %x\n", val, port & 0x7); + lm78_log("LM78: Write %02X to unknown ISA port %d\n", val, port & 0x7); break; } } @@ -258,7 +258,7 @@ lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank) { lm75_t *lm75; - lm78_log("LM78: write(%02x, %d, %02x)\n", reg, bank, val); + lm78_log("LM78: write(%02X, %d, %02X)\n", reg, bank, val); if (((reg >> 4) == 0x5) && (bank != 0)) { /* LM75 registers */ @@ -343,7 +343,7 @@ lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank) dev->active_bank = (dev->regs[0x4e] & 0x07); break; case 0x87: - /* fixes AS99127F boards hanging after save & exit, probably a reset register */ + /* fixes AS99127F boards hanging after BIOS save & exit, probably a reset register */ if ((dev->local & LM78_AS99127F) && (val == 0x01)) { lm78_log("LM78: Reset requested through AS99127F\n"); resetx86(); diff --git a/src/spd.c b/src/spd.c index 4b63c6d2c..84ba3eb84 100644 --- a/src/spd.c +++ b/src/spd.c @@ -73,7 +73,7 @@ spd_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv) { spd_t *dev = (spd_t *) priv; uint8_t ret = *(spd_data[dev->slot] + cmd); - spd_log("SPD: read(%02x, %02x) = %02x\n", addr, cmd, ret); + spd_log("SPD: read(%02X, %02X) = %02X\n", addr, cmd, ret); return ret; } @@ -195,7 +195,7 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) /* populate slot */ vslots[vslot] = (1 << log2_ui16(MIN(total_size, max_module_size))); if (total_size >= vslots[vslot]) { - spd_log("SPD: vslot %d = %d MB\n", vslot, vslots[vslot]); + spd_log("SPD: initial vslot %d = %d MB\n", vslot, vslots[vslot]); total_size -= vslots[vslot]; } else { vslots[vslot] = 0; From f236a44b0879b396071ffca4391db578cd10e63d Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 18 May 2020 23:02:42 -0300 Subject: [PATCH 12/12] Change 370SLM name again to be consistent with other Supermicro boards --- 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 f9f4c5dce..cce8106a9 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -320,7 +320,7 @@ const machine_t machines[] = { /* PGA370 machines */ /* 440LX */ #if defined(DEV_BRANCH) && defined(NO_SIO) - { "[Socket 370 LX] Supermicro SUPER 370SLM","s370slm", {{"Intel", cpus_Celeron}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_s370slm_init, NULL }, + { "[Socket 370 LX] Supermicro 370SLM", "s370slm", {{"Intel", cpus_Celeron}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_s370slm_init, NULL }, #endif /* 440BX */ { "[Socket 370 BX] ASUS CUBX", "cubx", {{"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 },