From 84a230a2824af29350671e59682c89d67a51484a Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 30 Oct 2020 20:41:15 -0300 Subject: [PATCH] Hardware monitoring overhaul --- src/device/hwm.c | 76 +++++- src/device/hwm_gl518sm.c | 93 ++++--- src/device/hwm_lm75.c | 101 +++---- src/device/hwm_lm78.c | 509 +++++++++++++++++++++-------------- src/device/hwm_vt82c686.c | 66 +++-- src/include/86box/hwm.h | 12 +- src/machine/m_at_386dx_486.c | 24 +- src/machine/m_at_slot1.c | 173 ++---------- src/machine/m_at_slot2.c | 85 +----- src/machine/m_at_socket370.c | 91 +------ src/machine/m_at_socket7.c | 119 +------- src/machine/m_at_socket8.c | 6 +- src/machine/m_at_sockets7.c | 48 ---- 13 files changed, 584 insertions(+), 819 deletions(-) diff --git a/src/device/hwm.c b/src/device/hwm.c index 7ef55b3ef..0205edcde 100644 --- a/src/device/hwm.c +++ b/src/device/hwm.c @@ -15,23 +15,81 @@ * Copyright 2020 RichardG. */ +#include +#include #include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> #include <86box/device.h> +#include "cpu.h" +#include <86box/machine.h> #include <86box/hwm.h> -hwm_values_t hwm_values; +/* Refer to specific hardware monitor implementations for the meaning of hwm_values. */ +hwm_values_t hwm_values; -void -hwm_set_values(hwm_values_t new_values) +uint16_t +hwm_get_vcore() { - hwm_values = new_values; -} + /* Determine Vcore for the active CPU. */ + CPU *cpu = &machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective]; + switch (cpu->cpu_type) { + case CPU_WINCHIP: + case CPU_WINCHIP2: +#if defined(DEV_BRANCH) && defined(USE_AMD_K5) + case CPU_K5: + case CPU_5K86: +#endif +#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86))) + case CPU_Cx6x86: +#endif + return 3520; + case CPU_PENTIUMMMX: + return ((cpu->cpuid_model & 0xf000) == 0x1000) ? 3300 : 2800; -hwm_values_t* -hwm_get_values() -{ - return &hwm_values; +#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86))) + case CPU_Cx6x86MX: + return (cpu->rspeed == 208333333) ? 2700 : 2900; + + case CPU_Cx6x86L: +#endif + case CPU_PENTIUM2: + return 2800; + + case CPU_K6_2C: + if (cpu->multi == 5.0) + return 2400; + else if (cpu->rspeed >= 550000000) + return 2300; + else + return 2200; + + case CPU_K6: + if ((cpu->cpuid_model & 0x0f0) == 0x070) + return 2200; + else if (cpu->multi <= 3.0) + return 2900; + else + return 3200; + + case CPU_K6_2: + case CPU_K6_3: + return 2200; + + case CPU_PENTIUM2D: + case CPU_CYRIX3S: + return 2050; + + case CPU_K6_2P: + case CPU_K6_3P: + return 2000; + + default: + return 3300; + } } diff --git a/src/device/hwm_gl518sm.c b/src/device/hwm_gl518sm.c index e09c29443..aca9f95a4 100644 --- a/src/device/hwm_gl518sm.c +++ b/src/device/hwm_gl518sm.c @@ -24,7 +24,6 @@ #include <86box/86box.h> #include <86box/device.h> #include <86box/io.h> -#include "cpu.h" #include <86box/smbus.h> #include <86box/hwm.h> @@ -83,14 +82,14 @@ gl518sm_remap(gl518sm_t *dev, uint8_t addr) gl518sm_log("GL518SM: remapping to SMBus %02Xh\n", addr); smbus_removehandler(dev->smbus_addr, 1, - gl518sm_smbus_read_byte, gl518sm_smbus_read_byte_cmd, gl518sm_smbus_read_word_cmd, NULL, - gl518sm_smbus_write_byte, gl518sm_smbus_write_byte_cmd, gl518sm_smbus_write_word_cmd, NULL, - dev); + gl518sm_smbus_read_byte, gl518sm_smbus_read_byte_cmd, gl518sm_smbus_read_word_cmd, NULL, + gl518sm_smbus_write_byte, gl518sm_smbus_write_byte_cmd, gl518sm_smbus_write_word_cmd, NULL, + dev); if (addr < 0x80) smbus_sethandler(addr, 1, - gl518sm_smbus_read_byte, gl518sm_smbus_read_byte_cmd, gl518sm_smbus_read_word_cmd, NULL, - gl518sm_smbus_write_byte, gl518sm_smbus_write_byte_cmd, gl518sm_smbus_write_word_cmd, NULL, - dev); + gl518sm_smbus_read_byte, gl518sm_smbus_read_byte_cmd, gl518sm_smbus_read_word_cmd, NULL, + gl518sm_smbus_write_byte, gl518sm_smbus_write_byte_cmd, gl518sm_smbus_write_word_cmd, NULL, + dev); dev->smbus_addr = addr; } @@ -126,13 +125,14 @@ gl518sm_read(gl518sm_t *dev, uint8_t reg) uint16_t ret = dev->regs[reg & 0x1f]; switch (reg) { - case 0x07: case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: - /* two-byte registers: leave as-is */ - break; - default: - /* single-byte registers: duplicate low byte to high byte (real hardware behavior unknown) */ - ret |= (ret << 8); - break; + case 0x07: case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: + /* two-byte registers: leave as-is */ + break; + + default: + /* single-byte registers: duplicate low byte to high byte (real hardware behavior unknown) */ + ret |= (ret << 8); + break; } gl518sm_log("GL518SM: read(%02X) = %04X\n", reg, ret); @@ -171,36 +171,36 @@ gl518sm_write(gl518sm_t *dev, uint8_t reg, uint16_t val) gl518sm_log("GL518SM: write(%02X, %04X)\n", reg, val); switch (reg) { - case 0x00: case 0x01: case 0x04: case 0x07: case 0x0d: case 0x12: case 0x13: case 0x14: case 0x15: - /* read-only registers */ - return 0; + case 0x00: case 0x01: case 0x04: case 0x07: case 0x0d: case 0x12: case 0x13: case 0x14: case 0x15: + /* read-only registers */ + return 0; - case 0x0a: - dev->regs[0x13] = (val & 0xff); - break; + case 0x0a: + dev->regs[0x13] = (val & 0xff); + break; - case 0x03: - dev->regs[reg] = (val & 0xfc); + case 0x03: + dev->regs[reg] = (val & 0xfc); - if (val & 0x80) /* Init */ - gl518sm_reset(dev); - break; + if (val & 0x80) /* Init */ + gl518sm_reset(dev); + break; - case 0x0f: - dev->regs[reg] = (val & 0xf8); + case 0x0f: + dev->regs[reg] = (val & 0xf8); - /* update fan values to match the new divisor */ - dev->regs[0x07] = (GL518SM_RPM_TO_REG(dev->values->fans[0], 1 << ((dev->regs[0x0f] >> 6) & 0x3)) << 8); - dev->regs[0x07] |= GL518SM_RPM_TO_REG(dev->values->fans[1], 1 << ((dev->regs[0x0f] >> 4) & 0x3)); - break; + /* update fan values to match the new divisor */ + dev->regs[0x07] = (GL518SM_RPM_TO_REG(dev->values->fans[0], 1 << ((dev->regs[0x0f] >> 6) & 0x3)) << 8); + dev->regs[0x07] |= GL518SM_RPM_TO_REG(dev->values->fans[1], 1 << ((dev->regs[0x0f] >> 4) & 0x3)); + break; - case 0x11: - dev->regs[reg] = (val & 0x7f); - break; + case 0x11: + dev->regs[reg] = (val & 0x7f); + break; - default: - dev->regs[reg] = val; - break; + default: + dev->regs[reg] = val; + break; } return 1; @@ -250,7 +250,22 @@ gl518sm_init(const device_t *info) memset(dev, 0, sizeof(gl518sm_t)); dev->local = info->local; - dev->values = hwm_get_values(); + + /* Set default values. */ + hwm_values_t defaults = { + { /* fan speeds */ + 3000, /* System */ + 3000 /* CPU */ + }, { /* temperatures */ + 30 /* CPU */ + }, { /* voltages */ + hwm_get_vcore(), /* Vcore */ + RESISTOR_DIVIDER(12000, 150, 47), /* +12V (15K/4.7K divider suggested in the GL518SM datasheet) */ + 3300 /* +3.3V */ + } + }; + hwm_values = defaults; + dev->values = &hwm_values; gl518sm_reset(dev); gl518sm_remap(dev, dev->local & 0x7f); @@ -259,6 +274,7 @@ gl518sm_init(const device_t *info) } +/* GL518SM on SMBus address 2Ch */ const device_t gl518sm_2c_device = { "Genesys Logic GL518SM Hardware Monitor", DEVICE_ISA, @@ -268,6 +284,7 @@ const device_t gl518sm_2c_device = { NULL }; +/* GL518SM on SMBus address 2Dh */ const device_t gl518sm_2d_device = { "Genesys Logic GL518SM Hardware Monitor", DEVICE_ISA, diff --git a/src/device/hwm_lm75.c b/src/device/hwm_lm75.c index ec5dd500c..7210cf8ef 100644 --- a/src/device/hwm_lm75.c +++ b/src/device/hwm_lm75.c @@ -65,14 +65,14 @@ lm75_remap(lm75_t *dev, uint8_t addr) lm75_log("LM75: remapping to SMBus %02Xh\n", addr); if (dev->smbus_addr < 0x80) 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); + 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 (addr < 0x80) smbus_sethandler(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); + 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); dev->smbus_addr = addr; } @@ -101,21 +101,21 @@ lm75_smbus_read_word_cmd(uint8_t addr, uint8_t cmd, void *priv) 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; + 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 */ @@ -131,9 +131,13 @@ lm75_read(lm75_t *dev, uint8_t reg) 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 > 0x7) && ((reg & 0xf8) != 0x50) && (dev->as99127f_smbus_addr < 0x80)) - ret = smbus_read_byte_cmd(dev->as99127f_smbus_addr, reg); + ret = smbus_read_byte_cmd(dev->as99127f_smbus_addr, reg); + else if ((reg & 0x7) == 0x0) /* temperature high byte */ + ret = LM75_TEMP_TO_REG(dev->values->temperatures[dev->local >> 8]) >> 8; + else if ((reg & 0x7) == 0x1) /* temperature low byte */ + ret = LM75_TEMP_TO_REG(dev->values->temperatures[dev->local >> 8]); else - ret = dev->regs[reg & 0x7]; + ret = dev->regs[reg & 0x7]; lm75_log("LM75: read(%02X) = %02X\n", reg, ret); @@ -165,22 +169,22 @@ lm75_smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val, void *priv) 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; + 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; } } @@ -194,14 +198,14 @@ lm75_write(lm75_t *dev, uint8_t reg, uint8_t val) 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 > 0x7) && ((reg & 0xf8) != 0x50) && (dev->as99127f_smbus_addr < 0x80)) { - smbus_write_byte_cmd(dev->as99127f_smbus_addr, reg, val); - return 1; + 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 */ + return 0; /* read-only registers */ dev->regs[reg_idx] = val; @@ -212,9 +216,6 @@ lm75_write(lm75_t *dev, uint8_t reg, uint8_t val) 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; @@ -240,7 +241,11 @@ lm75_init(const device_t *info) memset(dev, 0, sizeof(lm75_t)); dev->local = info->local; - dev->values = hwm_get_values(); + + /* Set default value. */ + if (dev->local) + hwm_values.temperatures[dev->local >> 8] = 30; + dev->values = &hwm_values; dev->as99127f_smbus_addr = 0x80; @@ -253,7 +258,7 @@ lm75_init(const device_t *info) /* LM75 on SMBus address 4Ah, reporting temperatures[1]. */ const device_t lm75_1_4a_device = { "National Semiconductor LM75 Temperature Sensor", - DEVICE_AT, + DEVICE_ISA, 0x14a, lm75_init, lm75_close, NULL, NULL, NULL, NULL, @@ -265,7 +270,7 @@ const device_t lm75_1_4a_device = { the Winbond W83781D family. Not to be used stand-alone. */ const device_t lm75_w83781d_device = { "Winbond W83781D Secondary Temperature Sensor", - DEVICE_AT, + DEVICE_ISA, 0, lm75_init, lm75_close, NULL, NULL, NULL, NULL, diff --git a/src/device/hwm_lm78.c b/src/device/hwm_lm78.c index 829e323ce..36a669533 100644 --- a/src/device/hwm_lm78.c +++ b/src/device/hwm_lm78.c @@ -29,12 +29,13 @@ #include <86box/hwm.h> -#define LM78_SMBUS 0x10000 -#define LM78_W83781D 0x20000 -#define LM78_AS99127F_REV1 0x40000 -#define LM78_AS99127F_REV2 0x80000 +#define LM78_SMBUS 0x010000 +#define LM78_W83781D 0x020000 +#define LM78_AS99127F_REV1 0x040000 +#define LM78_AS99127F_REV2 0x080000 +#define LM78_W83782D 0x100000 #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 (LM78_W83781D | LM78_AS99127F | LM78_W83782D) /* 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))) @@ -48,6 +49,7 @@ typedef struct { device_t *lm75[2]; uint8_t regs[256]; + uint8_t regs_782d[2][16]; uint8_t addr_register; uint8_t data_register; @@ -69,7 +71,7 @@ static void lm78_smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val, v 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); - +#define ENABLE_LM78_LOG 1 #ifdef ENABLE_LM78_LOG int lm78_do_log = ENABLE_LM78_LOG; @@ -100,25 +102,25 @@ lm78_remap(lm78_t *dev, uint8_t addr) lm78_log("LM78: remapping to SMBus %02Xh\n", addr); 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); + 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 (addr < 0x80) smbus_sethandler(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); + 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); dev->smbus_addr = addr; 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; - } + /* 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; + } } } @@ -130,22 +132,23 @@ lm78_isa_read(uint16_t port, void *priv) uint8_t ret = 0xff; switch (port & 0x7) { - case 0x5: - ret = (dev->addr_register & 0x7f); - break; - case 0x6: - ret = lm78_read(dev, dev->addr_register, dev->active_bank); + 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; - default: - lm78_log("LM78: Read from unknown ISA port %d\n", port & 0x7); - break; + 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)))) || + ((dev->local & LM78_W83782D) && (dev->active_bank == 5) && (dev->addr_register >= 0x50) && (dev->addr_register < 0x58))) { + /* auto-increment registers */ + dev->addr_register++; + } + break; + default: + lm78_log("LM78: Read from unknown ISA port %d\n", port & 0x7); + break; } return ret; @@ -179,24 +182,50 @@ 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) { - uint8_t ret = 0; + uint8_t ret = 0, masked_reg = reg; lm75_t *lm75; - if (((reg & 0xf8) == 0x50) && (bank != 0)) { - /* LM75 registers */ - lm75 = device_get_priv(dev->lm75[bank - 1]); - if (lm75) - ret = lm75_read(lm75, reg); + if (((reg & 0xf8) == 0x50) && ((bank == 1) || (bank == 2))) { + /* LM75 registers */ + lm75 = device_get_priv(dev->lm75[bank - 1]); + if (lm75) + ret = lm75_read(lm75, reg); + } else if (((reg & 0xf8) == 0x50) && ((bank == 4) || (bank == 5) || (bank == 6))) { + /* W83782D additional registers */ + if (dev->local & LM78_W83782D) { + if ((bank == 5) && ((reg == 0x50) || (reg == 0x51))) /* voltages */ + ret = LM78_VOLTAGE_TO_REG(dev->values->voltages[7 + (reg & 1)]); + else if (bank < 6) + ret = dev->regs_782d[bank - 4][reg & 0x0f]; + } } 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 [0x00:0x12] to [0x80:0x92] */ - ret = dev->regs[reg & 0x7f]; - else - ret = dev->regs[reg]; + /* regular registers */ + ret = dev->regs[reg]; + if (reg >= 0x40) + masked_reg = reg & 0x3f; /* match both non-auto-increment and auto-increment locations */ + if ((masked_reg >= 0x20) && (masked_reg <= 0x26)) /* voltages */ + ret = LM78_VOLTAGE_TO_REG(dev->values->voltages[reg & 7]); + else if (masked_reg == 0x27) /* temperature */ + ret = dev->values->temperatures[0]; + else if ((masked_reg >= 0x28) && (masked_reg <= 0x2a)) /* fan speeds */ + ret = LM78_RPM_TO_REG(dev->values->fans[reg & 3], 1 << ((dev->regs[((reg & 3) == 2) ? 0x4b : 0x47] >> ((reg & 3) ? 6 : 4)) & 0x3)); + else if ((reg == 0x4f) && (dev->local & LM78_WINBOND)) /* two-byte vendor ID register */ + 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 (dev->local & LM78_AS99127F) { /* AS99127F mirrored registers */ + masked_reg = reg & 0x7f; + if (masked_reg == 0x00) /* IN2 Low Limit */ + ret = dev->regs[0x30]; + else if ((masked_reg == 0x01) || (masked_reg == 0x04)) /* IN3 */ + ret = LM78_VOLTAGE_TO_REG(dev->values->voltages[3]); + else if (masked_reg == 0x05) /* IN2 */ + ret = LM78_VOLTAGE_TO_REG(dev->values->voltages[2]); + else if (masked_reg == 0x08) /* IN3 Low Limit */ + ret = dev->regs[0x32]; + else if ((reg >= 0x80) && (reg <= 0x92)) /* mirror [0x00:0x12] to [0x80:0x92] */ + ret = dev->regs[masked_reg]; + } } lm78_log("LM78: read(%02X, %d) = %02X\n", reg, bank, ret); @@ -211,22 +240,23 @@ lm78_isa_write(uint16_t port, uint8_t val, void *priv) lm78_t *dev = (lm78_t *) priv; switch (port & 0x7) { - case 0x5: - dev->addr_register = (val & 0x7f); - break; - case 0x6: - lm78_write(dev, dev->addr_register, val, dev->active_bank); + 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; - default: - lm78_log("LM78: Write %02X to unknown ISA port %d\n", val, port & 0x7); - break; + 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)))) || + ((dev->local & LM78_W83782D) && (dev->active_bank == 5) && (dev->addr_register >= 0x50) && (dev->addr_register < 0x58))) { + /* auto-increment registers */ + dev->addr_register++; + } + break; + default: + lm78_log("LM78: Write %02X to unknown ISA port %d\n", val, port & 0x7); + break; } } @@ -262,90 +292,114 @@ lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank) lm78_log("LM78: write(%02X, %d, %02X)\n", reg, bank, val); - if (((reg & 0xf8) == 0x50) && (bank != 0)) { - /* LM75 registers */ - lm75 = device_get_priv(dev->lm75[bank - 1]); - if (lm75) - lm75_write(lm75, reg, val); - return 1; + if ((reg & 0xf8) == 0x50) { + if ((bank == 1) || (bank == 2)) { + /* LM75 registers */ + lm75 = device_get_priv(dev->lm75[bank - 1]); + if (lm75) + lm75_write(lm75, reg, val); + return 1; + } else if (dev->local & LM78_W83782D) { + /* W83782D additional registers */ + if (bank == 4) { + switch (reg) { + case 0x50: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: + case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5d: case 0x5e: case 0x5f: + /* read-only registers */ + return 0; + } + + dev->regs_782d[0][reg & 0x0f] = val; + return 1; + } else if (bank == 5) { + switch (reg) { + case 0x50: case 0x51: case 0x52: case 0x53: case 0x58: case 0x59: case 0x5a: + case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: + /* read-only registers */ + return 0; + } + + dev->regs_782d[1][reg & 0x0f] = val; + return 1; + } else if (bank == 6) { + return 0; + } + } } /* 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; + 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; + dev->regs[reg & 0x3f] = val; else if ((reg >= 0x80) && (reg <= 0x92)) /* AS99127F mirrors [0x00:0x12] to [0x80:0x92] */ - dev->regs[reg & 0x7f] = val; + dev->regs[reg & 0x7f] = val; else - dev->regs[reg] = val; + 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) - lm78_remap(dev, dev->regs[0x48] & 0x7f); - 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 LM75 SMBus addresses (Winbond only) */ - if (dev->local & LM78_SMBUS) { - for (uint8_t i = 0; i <= 1; i++) { - lm75 = device_get_priv(dev->lm75[i]); - if (!lm75) - continue; - if (dev->regs[0x4a] & (0x08 * (0x10 * i))) /* DIS_T2 and DIS_T3 bit disable those interfaces */ - lm75_remap(lm75, 0x80); - else - lm75_remap(lm75, 0x48 + ((dev->regs[0x4a] >> (i * 4)) & 0x7)); - } - } - 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 BIOS save & exit, probably a reset register */ - if ((dev->local & LM78_AS99127F) && (val == 0x01)) { - lm78_log("LM78: Reset requested through AS99127F\n"); - resetx86(); - } - break; + case 0x40: + if (val & 0x80) /* INITIALIZATION bit resets all registers except main SMBus address */ + lm78_reset(dev, 1); + break; + + case 0x48: + /* set main SMBus address */ + if (dev->local & LM78_SMBUS) + lm78_remap(dev, dev->regs[0x48] & 0x7f); + 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 LM75 SMBus addresses (Winbond only) */ + if (dev->local & LM78_SMBUS) { + for (uint8_t i = 0; i <= 1; i++) { + lm75 = device_get_priv(dev->lm75[i]); + if (!lm75) + continue; + if (dev->regs[0x4a] & (0x08 * (0x10 * i))) /* DIS_T2 and DIS_T3 bit disable those interfaces */ + lm75_remap(lm75, 0x80); + else + lm75_remap(lm75, 0x48 + ((dev->regs[0x4a] >> (i * 4)) & 0x7)); + } + } + 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: + /* AS99127F boards perform a soft reset through this register */ + if ((dev->local & LM78_AS99127F) && (val == 0x01)) { + lm78_log("LM78: Reset requested through AS99127F\n"); + resetx86(); + } + break; } return 1; @@ -358,69 +412,65 @@ 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 */ - 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 = 0x2d; - dev->regs[0x48] = dev->smbus_addr; - if (dev->local & LM78_WINBOND) - dev->regs[0x4a] = 0x01; + if (!initialization) /* don't reset main SMBus address if the reset was triggered by the INITIALIZATION bit */ + dev->smbus_addr = 0x2d; + dev->regs[0x48] = dev->smbus_addr; + if (dev->local & LM78_WINBOND) + dev->regs[0x4a] = 0x01; } else { - dev->regs[0x48] = 0x00; - if (dev->local & LM78_WINBOND) - dev->regs[0x4a] = 0x88; + dev->regs[0x48] = 0x00; + if (dev->local & LM78_WINBOND) + dev->regs[0x4a] = 0x88; } 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; + 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 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; 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 */ - 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; + /* 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 */ + /* 0x01 appears to mirror IN3 */ + 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; + /* 0x04 appears to mirror IN3 */ + /* 0x05 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; - } + 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 if (dev->local & LM78_W83781D) { + dev->regs[0x58] = 0x10; + } else if (dev->local & LM78_W83782D) { + dev->regs[0x58] = 0x30; + } } else { - dev->regs[0x49] = 0x40; + dev->regs[0x49] = 0x40; } lm78_remap(dev, dev->smbus_addr); @@ -434,7 +484,7 @@ lm78_close(void *priv) uint16_t isa_io = (dev->local & 0xffff); if (isa_io) - io_removehandler(isa_io, 8, 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); } @@ -447,27 +497,61 @@ lm78_init(const device_t *info) memset(dev, 0, sizeof(lm78_t)); dev->local = info->local; - dev->values = hwm_get_values(); - /* initialize secondary/tertiary LM75 sensors on Winbond */ + /* Set default values. */ + hwm_values_t defaults = { + { /* fan speeds */ + 3000, /* usually Chassis, sometimes CPU */ + 3000, /* usually CPU, sometimes Chassis */ + 3000 /* usually PSU, sometimes Chassis */ + }, { /* temperatures */ + 30, /* usually Board, sometimes Chassis */ + 30, /* Winbond only: usually CPU, sometimes Probe */ + 30 /* Winbond only: usually CPU when not the one above */ + }, { /* voltages */ + hwm_get_vcore(), /* Vcore */ + 0, /* sometimes Vtt, Vio or second CPU */ + 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) */ + 12000 * (604.0 / 2100.0), /* -12V (Rf/Rin negative voltage formula from the W83781D datasheet) */ + 5000 * (604.0 / 909.0), /* -5V (Rf/Rin negative voltage formula from the W83781D datasheet) */ + RESISTOR_DIVIDER(5000, 51, 75), /* W83782D only: +5VSB (5.1K/7.5K divider suggested in the datasheet) */ + 3000 /* W83782D only: VBAT */ + } + }; + + /* Set per-chip defaults. */ + if (dev->local & LM78_AS99127F) { + defaults.voltages[5] = 12000 * (604.0 / 2400.0); /* different -12V Rin for AS99127F (bruteforced) */ + } else if (dev->local & LM78_W83782D) { + /* different negative voltage formula for W83782D (from the datasheet) */ + defaults.voltages[5] = ((3600 + 12000) * (232.0 / (232.0 + 56.0))) - 12000; + defaults.voltages[6] = ((3600 + 5000) * (120.0 / (120.0 + 56.0))) - 5000; + } + + hwm_values = defaults; + dev->values = &hwm_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; - } + 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, 8, 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; } @@ -495,8 +579,8 @@ const device_t w83781d_device = { }; -/* The ASUS AS99127F is a customized W83781D with no ISA interface (SMBus only), - added proprietary registers and different chip/vendor IDs. */ +/* 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, @@ -510,9 +594,20 @@ const device_t as99127f_device = { /* 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, + DEVICE_ISA, LM78_SMBUS | LM78_AS99127F_REV2, lm78_init, lm78_close, NULL, NULL, NULL, NULL, NULL }; + + +/* Winbond W83782D on ISA and SMBus. */ +const device_t w83782d_device = { + "Winbond W83782D Hardware Monitor", + DEVICE_ISA, + 0x290 | LM78_SMBUS | LM78_W83782D, + lm78_init, lm78_close, NULL, + NULL, NULL, NULL, + NULL +}; \ No newline at end of file diff --git a/src/device/hwm_vt82c686.c b/src/device/hwm_vt82c686.c index 475162eef..6c79cdb55 100644 --- a/src/device/hwm_vt82c686.c +++ b/src/device/hwm_vt82c686.c @@ -24,16 +24,15 @@ #include <86box/86box.h> #include <86box/device.h> #include <86box/io.h> -#include "cpu.h" #include <86box/smbus.h> #include <86box/hwm.h> -#define CLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a))) +#define CLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a))) #define VT82C686_RPM_TO_REG(r, d) ((r) ? CLAMP(1350000 / (r * d), 1, 255) : 0) -/* Temperature formula from source comments in Linux's via686a.c driver */ +/* Temperature/voltage formulas and factors derived from Linux's via686a.c driver */ #define VT82C686_TEMP_TO_REG(t) (-1.160370e-10*(t*t*t*t*t*t) + 3.193693e-08*(t*t*t*t*t) - 1.464447e-06*(t*t*t*t) - 2.525453e-04*(t*t*t) + 1.424593e-02*(t*t) + 2.148941e+00*t + 7.275808e+01) -#define VT82C686_VOLTAGE_TO_REG(v) ((v) >> 4) +#define VT82C686_VOLTAGE_TO_REG(v, f) CLAMP((((v) * (2.628 / (f))) - 120.5) / 25, 0, 255) typedef struct { @@ -67,10 +66,10 @@ vt82c686_write(uint16_t port, uint8_t val, void *priv) return; switch (reg) { - case 0x40: - if (val & 0x80) - vt82c686_reset(dev, 1); - break; + case 0x40: + if (val & 0x80) + vt82c686_reset(dev, 1); + break; case 0x47: val &= 0xf0; @@ -92,19 +91,19 @@ vt82c686_hwm_write(uint8_t addr, uint8_t val, void *priv) vt82c686_t *dev = (vt82c686_t *) priv; if (dev->io_base) - io_removehandler(dev->io_base, 0x0050, + io_removehandler(dev->io_base, 0x0050, vt82c686_read, NULL, NULL, vt82c686_write, NULL, NULL, dev); switch (addr) { - case 0x70: - dev->io_base &= 0xff00; - dev->io_base |= val & 0x80; - break; + case 0x70: + dev->io_base &= 0xff00; + dev->io_base |= val & 0x80; + break; - case 0x71: - dev->io_base &= 0x00ff; - dev->io_base |= val << 8; - break; + case 0x71: + dev->io_base &= 0x00ff; + dev->io_base |= val << 8; + break; case 0x74: dev->enable = val & 0x01; @@ -112,7 +111,7 @@ vt82c686_hwm_write(uint8_t addr, uint8_t val, void *priv) } if (dev->enable && dev->io_base) - io_sethandler(dev->io_base, 0x0050, + io_sethandler(dev->io_base, 0x0050, vt82c686_read, NULL, NULL, vt82c686_write, NULL, NULL, dev); } @@ -126,11 +125,11 @@ vt82c686_reset(vt82c686_t *dev, uint8_t initialization) dev->regs[0x20] = VT82C686_TEMP_TO_REG(dev->values->temperatures[0]); dev->regs[0x21] = VT82C686_TEMP_TO_REG(dev->values->temperatures[1]); - dev->regs[0x22] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[0]); - dev->regs[0x23] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[1]); - dev->regs[0x24] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[2]); - dev->regs[0x25] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[3]); - dev->regs[0x26] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[4]); + dev->regs[0x22] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[0], 1.25); + dev->regs[0x23] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[1], 1.25); + dev->regs[0x24] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[2], 1.67); + dev->regs[0x25] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[3], 2.6); + dev->regs[0x26] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[4], 6.3); dev->regs[0x29] = VT82C686_RPM_TO_REG(dev->values->fans[0], 2); dev->regs[0x2a] = VT82C686_RPM_TO_REG(dev->values->fans[1], 2); @@ -162,7 +161,26 @@ vt82c686_init(const device_t *info) vt82c686_t *dev = (vt82c686_t *) malloc(sizeof(vt82c686_t)); memset(dev, 0, sizeof(vt82c686_t)); - dev->values = hwm_get_values(); + /* Set default values. Since this hardware monitor has a complex voltage factor system, + the values struct contains voltage values *before* applying their respective factors. */ + hwm_values_t defaults = { + { /* fan speeds */ + 3000, /* CPU */ + 3000 /* Chassis */ + }, { /* temperatures */ + 30, /* CPU */ + 30, /* System */ + 0 /* unused */ + }, { /* voltages */ + hwm_get_vcore(), /* Vcore */ + 2500, /* 2.5V */ + 3300, /* 3.3V */ + 5000, /* 5V */ + 12000 /* 12V */ + } + }; + hwm_values = defaults; + dev->values = &hwm_values; vt82c686_reset(dev, 0); diff --git a/src/include/86box/hwm.h b/src/include/86box/hwm.h index 70d835f01..72d5cc208 100644 --- a/src/include/86box/hwm.h +++ b/src/include/86box/hwm.h @@ -16,15 +16,16 @@ */ #ifndef EMU_HWM_H # define EMU_HWM_H +# include #define RESISTOR_DIVIDER(v, r1, r2) (((v) * (r2)) / ((r1) + (r2))) -typedef struct _hwm_values_ { +typedef struct { uint16_t fans[4]; uint8_t temperatures[4]; - uint16_t voltages[8]; + uint16_t voltages[9]; } hwm_values_t; typedef struct { @@ -40,8 +41,7 @@ typedef struct { } lm75_t; -extern void hwm_set_values(hwm_values_t new_values); -extern hwm_values_t* hwm_get_values(); +extern uint16_t hwm_get_vcore(); extern void lm75_remap(lm75_t *dev, uint8_t addr); extern uint8_t lm75_read(lm75_t *dev, uint8_t reg); @@ -50,6 +50,9 @@ extern uint8_t lm75_write(lm75_t *dev, uint8_t reg, uint8_t val); extern void vt82c686_hwm_write(uint8_t addr, uint8_t val, void *priv); +/* Refer to specific hardware monitor implementations for the meaning of hwm_values. */ +extern hwm_values_t hwm_values; + extern const device_t lm75_1_4a_device; extern const device_t lm75_w83781d_device; @@ -57,6 +60,7 @@ 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; +extern const device_t w83782d_device; extern const device_t gl518sm_2c_device; extern const device_t gl518sm_2d_device; diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 3afbdafb2..4440df5fb 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -918,26 +918,10 @@ machine_at_itoxstar_init(const machine_t *model) device_add(&keyboard_ps2_ami_pci_device); device_add(&stpc_client_device); device_add(&sst_flash_29ee020_device); - - hwm_values_t machine_hwm = { - { /* fan speeds (incorrect divisor for some reason) */ - 3000, /* Chassis */ - 3000 /* CPU */ - }, { /* temperatures */ - 30, /* Chassis */ - 30 /* CPU */ - }, { /* voltages */ - 0, /* unused */ - 0, /* unused */ - 3300, /* Vio */ - 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) */ - } - }; - hwm_set_values(machine_hwm); - device_add(&w83781d_device); + device_add(&w83781d_device); /* fans: Chassis, CPU, unused; temperatures: Chassis, CPU, unused */ + hwm_values.fans[2] = 0; /* unused */ + hwm_values.temperatures[2] = 0; /* unused */ + hwm_values.voltages[0] = 0; /* Vcore unused */ return ret; } diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index 15c353b34..328691ca2 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -81,26 +81,9 @@ machine_at_kn97_init(const machine_t *model) device_add(&keyboard_ps2_pci_device); device_add(&w83877f_device); device_add(&intel_flash_bxt_device); - - hwm_values_t machine_hwm = { - { /* fan speeds (incorrect divisor for some reason) */ - 6000, /* Chassis */ - 6000, /* CPU */ - 6000 /* Power */ - }, { /* temperatures */ - 30 /* MB */ - }, { /* voltages */ - 2800, /* VCORE (2.8V 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) */ - } - }; - hwm_set_values(machine_hwm); - device_add(&lm78_device); + device_add(&lm78_device); /* fans: Chassis, CPU, Power; temperature: MB */ + for (uint8_t i = 0; i < 3; i++) + hwm_values.fans[i] *= 2; /* BIOS reports fans with the wrong divisor for some reason */ return ret; } @@ -159,27 +142,8 @@ machine_at_spitfire_init(const machine_t *model) device_add(&keyboard_ps2_pci_device); device_add(&fdc37c935_device); device_add(&intel_flash_bxt_device); - spd_register(SPD_TYPE_SDRAM, 0xF, 256); - - hwm_values_t machine_hwm = { - { /* fan speeds (incorrect divisor for some reason) */ - 6000, /* Chassis */ - 6000, /* CPU */ - 6000 /* Power */ - }, { /* temperatures */ - 30 /* MB */ - }, { /* voltages */ - 2800, /* VCORE (2.8V 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) */ - } - }; - hwm_set_values(machine_hwm); - device_add(&lm78_device); + spd_register(SPD_TYPE_SDRAM, 0xF, 256); + device_add(&lm78_device); /* no reporting in BIOS */ return ret; } @@ -210,30 +174,9 @@ machine_at_p6i440e2_init(const machine_t *model) device_add(&w83977tf_device); device_add(&sst_flash_29ee010_device); spd_register(SPD_TYPE_SDRAM, 0x03, 256); - - hwm_values_t machine_hwm = { - { /* fan speeds */ - 3000, /* Chassis */ - 3000, /* CPU */ - 3000 /* Power */ - }, { /* temperatures */ - 30, /* MB */ - 0, /* unused */ - 27 /* CPU */ - }, { /* 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) */ - } - }; - 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); + device_add(&w83781d_device); /* fans: CPU, CHS, PS; temperatures: unused, CPU, System */ + hwm_values.temperatures[0] = 0; /* unused */ + hwm_values.voltages[1] = 1500; /* CPUVTT */ return ret; } @@ -268,30 +211,9 @@ machine_at_p2bls_init(const machine_t *model) device_add(&w83977ef_device); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); - - hwm_values_t machine_hwm = { - { /* fan speeds */ - 3000, /* Chassis */ - 3000, /* CPU */ - 3000 /* Power */ - }, { /* temperatures */ - 30, /* MB */ - 0, /* unused */ - 27 /* CPU */ - }, { /* 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) */ - } - }; - 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); + device_add(&w83781d_device); /* fans: Chassis, CPU, Power; temperatures: MB, unused, CPU */ + hwm_values.temperatures[1] = 0; /* unused */ + hwm_values.temperatures[2] -= 3; /* CPU offset */ return ret; } @@ -326,30 +248,8 @@ machine_at_p3bf_init(const machine_t *model) device_add(&w83977ef_device); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); - - hwm_values_t machine_hwm = { - { /* fan speeds */ - 3000, /* Chassis */ - 3000, /* CPU */ - 3000 /* Power */ - }, { /* temperatures */ - 30, /* MB */ - 30, /* JTPWR */ - 30 /* CPU */ - }, { /* voltages */ - 2050, /* VCORE (2.05V by default) */ - 0, /* unused */ - 3300, /* +3.3V */ - 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) */ - } - }; - 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(&as99127f_device); + device_add(&as99127f_device); /* fans: Chassis, CPU, Power; temperatures: MB, JTPWR, CPU */ + hwm_values.voltages[4] = hwm_values.voltages[5]; /* +12V reading not in line with other boards; appears to be close to the -12V reading */ return ret; } @@ -418,23 +318,7 @@ machine_at_ax6bc_init(const machine_t *model) device_add(&w83977tf_device); device_add(&sst_flash_29ee020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); - - hwm_values_t machine_hwm = { - { /* fan speeds */ - 3000, /* System */ - 3000 /* CPU */ - }, { /* temperatures */ - 30 /* CPU */ - }, { /* voltages */ - 2050, /* VCORE (2.05V by default) */ - RESISTOR_DIVIDER(12000, 150, 47), /* +12V (15K/4.7K divider suggested in the GL518SM datasheet) */ - 3300 /* +3.3V */ - } - }; - 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(&gl518sm_2d_device); + device_add(&gl518sm_2d_device); /* fans: System, CPU; temperature: CPU; no reporting in BIOS */ return ret; } @@ -502,30 +386,11 @@ machine_at_p6sba_init(const machine_t *model) device_add(&keyboard_ps2_ami_pci_device); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); - - hwm_values_t machine_hwm = { - { /* fan speeds */ - 3000, /* CPU1 */ - 0, /* CPU2 */ - 3000 /* Thermal Control */ - }, { /* temperatures */ - 0, /* unused */ - 30, /* CPU1 */ - 0 /* unused (CPU2?) */ - }, { /* voltages */ - 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) */ - } - }; - 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); + device_add(&w83781d_device); /* fans: CPU1, CPU2, Thermal Control; temperatures: unused, CPU1, CPU2? */ + hwm_values.fans[1] = 0; /* no CPU2 fan */ + hwm_values.temperatures[0] = 0; /* unused */ + hwm_values.temperatures[2] = 0; /* CPU2? */ + /* no CPU2 voltage */ return ret; } diff --git a/src/machine/m_at_slot2.c b/src/machine/m_at_slot2.c index 0306feaeb..7e0300412 100644 --- a/src/machine/m_at_slot2.c +++ b/src/machine/m_at_slot2.c @@ -67,30 +67,12 @@ machine_at_6gxu_init(const machine_t *model) device_add(&w83977ef_device); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0xF, 512); - - hwm_values_t machine_hwm = { - { /* fan speeds */ - 3000, /* Chassis */ - 3000, /* CPU */ - 3000 /* Power */ - }, { /* temperatures */ - 30, /* MB */ - 0, /* unused */ - 27 /* CPU */ - }, { /* 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) */ - } - }; - 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); + device_add(&w83782d_device); /* fans: ???, ???, System; temperatures: System, CPU, unused */ + hwm_values.fans[0] = 2000; + hwm_values.fans[1] = 2500; + hwm_values.fans[2] = 3000; + hwm_values.temperatures[2] = 0; /* unused */ + hwm_values.voltages[1] = 1500; /* VGTL */ return ret; } @@ -125,31 +107,11 @@ machine_at_s2dge_init(const machine_t *model) device_add(&w83977tf_device); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0xF, 512); + device_add(&w83781d_device); /* fans: CPU1, CPU2, Thermal Control; temperatures: unused, CPU1, CPU2? */ + hwm_values.fans[1] = 0; /* no CPU2 fan */ + hwm_values.temperatures[0] = 0; /* unused */ + hwm_values.temperatures[2] = 0; /* CPU2? */ - hwm_values_t machine_hwm = { - { /* fan speeds */ - 3000, /* CPU1 */ - 0, /* CPU2 */ - 3000 /* Thermal Control */ - }, { /* temperatures */ - 0, /* unused */ - 30, /* CPU1 */ - 20 /* unused (CPU2?) */ - }, { /* voltages */ - 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) */ - } - }; - 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); - return ret; } @@ -183,30 +145,9 @@ machine_at_fw6400gx_init(const machine_t *model) device_add(&pc87309_15c_device); device_add(&sst_flash_29ee020_device); spd_register(SPD_TYPE_SDRAM, 0xF, 512); + device_add(&w83781d_device); /* fans: Chassis, Power, CPU; temperatures: System, CPU, unused */ + hwm_values.temperatures[3] = 0; /* unused */ + hwm_values.voltages[1] = 1500; /* Vtt */ - hwm_values_t machine_hwm = { - { /* fan speeds */ - 3000, /* Chassis */ - 3000, /* Power */ - 3000 /* CPU */ - }, { /* temperatures */ - 30, /* System */ - 30, /* CPU */ - 0 /* unused */ - }, { /* voltages */ - 2050, /* Vcore (2.05V by default) */ - 1500, /* Vtt */ - 3300, /* Vio */ - 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) */ - } - }; - 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); - return ret; } diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index dfdbc67c2..dce2fb507 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -64,28 +64,9 @@ machine_at_s370slm_init(const machine_t *model) device_add(&keyboard_ps2_ami_pci_device); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); - - hwm_values_t machine_hwm = { - { /* fan speeds */ - 3000, /* CPU */ - 3000, /* Fan 2 */ - 3000 /* Chassis */ - }, { /* temperatures */ - 0, /* unused */ - 30, /* CPU */ - 0 /* unused */ - }, { /* voltages */ - 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) */ - } - }; - hwm_set_values(machine_hwm); - device_add(&w83781d_device); + device_add(&w83781d_device); /* fans: CPU, Fan 2, Chassis; temperatures: unused, CPU, unused */ + hwm_values.temperatures[0] = 0; /* unused */ + hwm_values.temperatures[2] = 0; /* unused */ return ret; } @@ -117,32 +98,10 @@ machine_at_cubx_init(const machine_t *model) device_add(&i440bx_device); device_add(&piix4e_device); device_add(&keyboard_ps2_ami_pci_device); - // device_add(&keyboard_ps2_pci_device); device_add(&w83977ef_device); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); - - hwm_values_t machine_hwm = { - { /* fan speeds */ - 3000, /* Chassis */ - 3000, /* CPU */ - 3000 /* Power */ - }, { /* temperatures */ - 30, /* MB */ - 30, /* JTPWR */ - 30 /* CPU */ - }, { /* 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, 59, 20), /* -12V (divider values bruteforced) */ - RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */ - } - }; - hwm_set_values(machine_hwm); - device_add(&as99127f_device); + device_add(&as99127f_device); /* fans: Chassis, CPU, Power; temperatures: MB, JTPWR, CPU */ return ret; } @@ -366,27 +325,6 @@ machine_at_6via85x_init(const machine_t *model) device_add(&keyboard_ps2_ami_pci_device); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); - - hwm_values_t machine_hwm = { - { /* fan speeds */ - 3000, /* Chassis */ - 3000, /* CPU */ - 3000 /* Power */ - }, { /* temperatures */ - 30, /* MB */ - 30, /* JTPWR */ - 30 /* CPU */ - }, { /* 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, 59, 20), /* -12V (divider values bruteforced) */ - RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */ - } - }; - hwm_set_values(machine_hwm); device_add(&via_vt82c686_hwm_device); return ret; @@ -419,27 +357,6 @@ machine_at_603tcf_init(const machine_t *model) device_add(&keyboard_ps2_ami_pci_device); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x3, 256); - - hwm_values_t machine_hwm = { - { /* fan speeds */ - 3000, /* Chassis */ - 3000, /* CPU */ - 3000 /* Power */ - }, { /* temperatures */ - 30, /* MB */ - 30, /* JTPWR */ - 30 /* CPU */ - }, { /* 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, 59, 20), /* -12V (divider values bruteforced) */ - RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */ - } - }; - hwm_set_values(machine_hwm); device_add(&via_vt82c686_hwm_device); return ret; diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 0d1ce9da7..f4d203536 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -817,41 +817,11 @@ machine_at_nupro592_init(const machine_t *model) device_add(&w83977ef_device); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x3, 128); - - 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); + device_add(&w83781d_device); /* fans: CPU1, unused, unused; temperatures: System, CPU1, unused */ + hwm_values.temperatures[2] = 0; /* unused */ + hwm_values.fans[1] = 0; /* unused */ + hwm_values.fans[2] = 0; /* unused */ + /* -5V is not reported by the BIOS, but leave it set */ return ret; } @@ -884,41 +854,13 @@ machine_at_tx97_init(const machine_t *model) 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 */ - 3000, /* Chassis */ - 3000, /* CPU */ - 3000 /* Power */ - }, { /* temperatures */ - 30, /* MB */ - 0, /* unused */ - 8 /* CPU */ - }, { /* 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) */ - } - }; - /* 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. */ - 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(&w83781d_device); /* fans: Chassis, CPU, Power; temperatures: MB, unused, CPU */ + hwm_values.temperatures[1] = 0; /* unused */ + /* CPU offset */ + if (hwm_values.temperatures[2] < 32) /* prevent underflow */ + hwm_values.temperatures[2] = 0; + else + hwm_values.temperatures[2] -= 32; return ret; } @@ -1014,41 +956,8 @@ machine_at_p5mms98_init(const machine_t *model) device_add(&w83977tf_device); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x3, 128); - - hwm_values_t machine_hwm = { - { /* fan speeds */ - 3000, /* Thermal */ - 3000, /* CPU */ - 3000 /* Chassis */ - }, { /* temperatures */ - 0, /* unused */ - 30 /* CPU */ - }, { /* voltages */ - 3300, /* VCORE (3.3V by default) */ - 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) */ - } - }; - /* 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. */ - 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(&lm78_device); - device_add(&lm75_1_4a_device); + device_add(&lm78_device); /* fans: Thermal, CPU, Chassis; temperature: unused */ + device_add(&lm75_1_4a_device); /* temperature: CPU */ return ret; } diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index 3d4b9c644..27702d53b 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -83,7 +83,7 @@ machine_at_mb600n_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(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x12, 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); @@ -209,7 +209,7 @@ machine_at_8500ttc_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(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); @@ -238,7 +238,7 @@ machine_at_m6mi_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(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x10, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); diff --git a/src/machine/m_at_sockets7.c b/src/machine/m_at_sockets7.c index 6bcab176a..5c433c7a6 100644 --- a/src/machine/m_at_sockets7.c +++ b/src/machine/m_at_sockets7.c @@ -135,54 +135,6 @@ machine_at_ficva503a_init(const machine_t *model) device_add(&via_vt82c686_sio_device); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); - - hwm_values_t machine_hwm = { - { /* fan speeds */ - 3000, /* CPUFAN1 */ - 3000 /* ChassisFAN */ - }, { /* temperatures */ - 32, /* CPU */ - 32, /* System */ - 0 /* unused */ - }, { /* voltages */ - 3300, /* Vcore (3.3V by default) */ - 2500, /* 2.5V (unused) */ - 3300, /* 3.3V */ - RESISTOR_DIVIDER(5000, 9, 16), /* 5V (divider values bruteforced) */ - RESISTOR_DIVIDER(12000, 28, 10) /* 12V (28K/10K divider applies to W83781D but is close enough) */ - } - }; - /* 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. */ - switch (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) { - case CPU_WINCHIP: - case CPU_WINCHIP2: -#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86))) - case CPU_Cx6x86: -#endif -#if defined(DEV_BRANCH) && defined(USE_AMD_K5) - case CPU_K5: - case CPU_5K86: -#endif - machine_hwm.voltages[0] = 3500; - break; -#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86))) - case CPU_Cx6x86MX: - machine_hwm.voltages[0] = 2900; - break; -#endif - case CPU_PENTIUMMMX: - machine_hwm.voltages[0] = 2800; - break; - case CPU_K6: - case CPU_K6_2: - machine_hwm.voltages[0] = 2200; - break; - } - machine_hwm.voltages[0] *= 1.32; /* multiplier bruteforced */ - hwm_set_values(machine_hwm); device_add(&via_vt82c686_hwm_device); return ret;