This commit is contained in:
Jasmine Iwanek
2022-07-26 16:32:27 -04:00
parent 8c5c8e51e1
commit d1dd3997dc
20 changed files with 712 additions and 470 deletions

View File

@@ -24,15 +24,18 @@
#include <86box/hwm.h>
#include <86box/nsc366.h>
/* Fan Algorithms */
#define FAN_TO_REG(val, div) ((val) <= 100 ? 0 : 480000 / ((val) * (div)))
#define FAN_DIV_FROM_REG(val) (1 << (((val) >> 5) & 0x03))
#define FAN_FROM_REG(val, div) ((val) == 0 ? 0 : 480000 / ((val) * (div)))
/* Voltage Algorithms */
#define IN_TO_REG(val, ref) ((val) < 0 ? 0 : (val) * 256 >= (ref) * 255 ? 255 : ((val) * 256 + (ref) / 2) / (ref))
#define IN_FROM_REG(val, ref) (((val) * (ref) + 128) / 256)
#define VREF (dev->vlm_config_global[0x08] & 2) ? 3025 : 2966 //VREF taken from pc87360.c
#define VLM_BANK dev->vlm_config_global[0x09]
/* Temperature Algorithms */
#define TEMP_TO_REG(val) ((val) < -55000 ? -55 : (val) > 127000 ? 127 : (val) < 0 ? ((val) - 500) / 1000 : ((val) + 500) / 1000)
#define TEMP_FROM_REG(val) ((val) * 1000)
#define TMS_BANK dev->tms_config_global[0x09]
@@ -60,7 +63,7 @@ nsc366_fscm_write(uint16_t addr, uint8_t val, void *priv)
{
nsc366_hwm_t *dev = (nsc366_hwm_t *)priv;
addr &= 0x0f;
addr &= 0x000f;
nsc366_hwm_log("NSC366 Fan Control: Write 0x%02x to register 0x%02x\n", val, addr);
@@ -97,7 +100,7 @@ nsc366_fscm_read(uint16_t addr, void *priv)
{
nsc366_hwm_t *dev = (nsc366_hwm_t *)priv;
addr &= 0x0f;
addr &= 0x000f;
switch(addr)
{
@@ -109,8 +112,11 @@ nsc366_fscm_read(uint16_t addr, void *priv)
case 0x07:
case 0x0a:
case 0x0d:
nsc366_hwm_log("NSC366 Fan Control: Reading %d RPM's from Bank %d\n", FAN_FROM_REG(dev->fscm_config[addr], FAN_DIV_FROM_REG(dev->fscm_config[0x06])), (addr - 7) / 3);
return dev->fscm_config[addr];
if(((addr == 0x07) && !!(dev->fscm_enable & 1)) || ((addr == 0x0a) && !!(dev->fscm_enable & 2)) || ((addr == 0x0d) && !!(dev->fscm_enable & 4))) {
nsc366_hwm_log("NSC366 Fan Control: Reading %d RPM's from Bank %d\n", FAN_FROM_REG(dev->fscm_config[addr], FAN_DIV_FROM_REG(dev->fscm_config[0x06])), (addr - 7) / 3);
return dev->fscm_config[addr];
}
else return 0;
default:
return 0;
@@ -135,7 +141,7 @@ nsc366_vlm_write(uint16_t addr, uint8_t val, void *priv)
{
nsc366_hwm_t *dev = (nsc366_hwm_t *)priv;
addr &= 0x0f;
addr &= 0x000f;
if(addr <= 9)
nsc366_hwm_log("NSC366 Voltage Monitor: Write 0x%02x to register 0x%02x\n", val, addr);
@@ -186,7 +192,7 @@ nsc366_vlm_read(uint16_t addr, void *priv)
{
nsc366_hwm_t *dev = (nsc366_hwm_t *)priv;
addr &= 0x0f;
addr &= 0x000f;
switch(addr)
{
@@ -202,8 +208,12 @@ nsc366_vlm_read(uint16_t addr, void *priv)
case 0x0b:
if (VLM_BANK < 13) {
nsc366_hwm_log("NSC366 Voltage Monitor: Reading %d Volts from Bank %d\n", IN_FROM_REG(dev->vlm_config_bank[VLM_BANK][1], VREF), VLM_BANK);
return dev->vlm_config_bank[VLM_BANK][1];
if (dev->vlm_config_bank[VLM_BANK][0] & 1) {
nsc366_hwm_log("NSC366 Voltage Monitor: Reading %d Volts from Bank %d\n", IN_FROM_REG(dev->vlm_config_bank[VLM_BANK][1], VREF), VLM_BANK);
return dev->vlm_config_bank[VLM_BANK][1];
}
else
return 0;
}
else
return 0;
@@ -231,7 +241,7 @@ nsc366_tms_write(uint16_t addr, uint8_t val, void *priv)
{
nsc366_hwm_t *dev = (nsc366_hwm_t *)priv;
addr &= 0x0f;
addr &= 0x000f;
if(addr <= 9)
nsc366_hwm_log("NSC366 Temperature Monitor: Write 0x%02x to register 0x%02x\n", val, addr);
@@ -262,7 +272,7 @@ nsc366_tms_write(uint16_t addr, uint8_t val, void *priv)
break;
case 0x0c ... 0x0e:
if(TMS_BANK < 13)
if(TMS_BANK < 3)
dev->tms_config_bank[TMS_BANK][addr - 0x0a] = val;
break;
}
@@ -274,9 +284,7 @@ nsc366_tms_read(uint16_t addr, void *priv)
{
nsc366_hwm_t *dev = (nsc366_hwm_t *)priv;
addr &= 0x0f;
addr++;
pclog("Reading %02x\n", addr);
addr &= 0x000f;
switch(addr)
{
@@ -285,12 +293,18 @@ nsc366_tms_read(uint16_t addr, void *priv)
case 0x0a:
case 0x0c ... 0x0e:
//return dev->tms_config_bank[TMS_BANK][addr - 0x0a];
return 1;
if(TMS_BANK < 4)
return dev->tms_config_bank[TMS_BANK][addr - 0x0a];
else return 0;
case 0x0b:
nsc366_hwm_log("NSC366 Temperature Monitor: Reading %d Degrees Celsius from Bank %d\n", TEMP_FROM_REG(dev->tms_config_bank[TMS_BANK][1]), TMS_BANK);
return dev->tms_config_bank[TMS_BANK][1];
if(TMS_BANK < 4) {
if (dev->vlm_config_bank[VLM_BANK][0] & 1) {
nsc366_hwm_log("NSC366 Temperature Monitor: Reading %d Degrees Celsius from Bank %d\n", TEMP_FROM_REG(dev->tms_config_bank[TMS_BANK][1]), TMS_BANK);
return dev->tms_config_bank[TMS_BANK][1];
}
else return 0;
}
default:
return 0;
@@ -316,6 +330,7 @@ nsc366_hwm_reset(void *priv)
{
nsc366_hwm_t *dev = (nsc366_hwm_t *)priv;
memset(dev->fscm_config, 0, sizeof(dev->fscm_config));
dev->fscm_enable = 0;
dev->fscm_addr = 0;
/* Get fan reports from defaults */
@@ -359,7 +374,7 @@ nsc366_hwm_init(const device_t *info)
nsc366_hwm_t *dev = (nsc366_hwm_t *)malloc(sizeof(nsc366_hwm_t));
memset(dev, 0, sizeof(nsc366_hwm_t));
/* Initialize the default values */
/* Initialize the default values (HWM is incomplete still) */
hwm_values_t defaults = {
{
3000, /* FAN 0 */
@@ -367,15 +382,24 @@ nsc366_hwm_init(const device_t *info)
3000 /* FAN 2 */
},
{
255, /* Temperature 0 */
255,
255,
155
30, /* Temperatures which are broken */
30,
30,
30
},
{
65535,
65535,
65535,
0, /* Voltages which are broken */
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
}
};
hwm_values = defaults;

View File

@@ -43,53 +43,51 @@ intel_ich2_trap_log(const char *fmt, ...)
#endif
void
intel_ich2_trap_set_acpi(intel_ich2_trap_t *trap, acpi_t *acpi)
intel_ich2_trap_set_acpi(intel_ich2_trap_t *dev, acpi_t *acpi)
{
trap->acpi = acpi;
dev->acpi = acpi;
}
static void
intel_ich2_trap_kick(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv)
{
intel_ich2_trap_t *trap = (intel_ich2_trap_t *) priv;
intel_ich2_trap_t *dev = (intel_ich2_trap_t *) priv;
intel_ich2_trap_log("Intel ICH2 Trap: Entered an I/O Trap. Provoking an SMI.\n");
acpi_raise_smi(trap->acpi, 1);
acpi_raise_smi(dev->acpi, 1);
}
void
intel_ich2_device_trap_setup(int enable, uint8_t acpi_reg, uint8_t acpi_reg_val, uint16_t addr, uint16_t size, int is_hdd, intel_ich2_trap_t *trap)
intel_ich2_device_trap_setup(uint8_t acpi_reg, uint8_t acpi_reg_val, uint16_t addr, uint16_t size, intel_ich2_trap_t *dev)
{
uint8_t acpi_trap_recieve = ((acpi_reg == 0x49) ? (trap->acpi->regs.devtrap_en >> 8) : (trap->acpi->regs.devtrap_en)) & 0xff; // Check if the decoded range is enabled on ACPIS
int acpi_enable = !!(acpi_trap_recieve & acpi_reg_val);
int trap_enabled = acpi_enable && enable;
uint8_t acpi_reg_recieve = dev->acpi->regs.devtrap_en >> ((acpi_reg & 1) * 8); /* Trap register is 16-bit on ranged ACPIBASE + 48h-49h */
int enable = !!(acpi_reg_recieve & acpi_reg_val); /* If enabled. Settle in the I/O trap */
if(trap_enabled)
{
intel_ich2_trap_log("Intel ICH2 Trap: An I/O has been enabled on range 0x%x\n", addr);
io_trap_add(intel_ich2_trap_kick, trap->trap);
}
if(enable)
intel_ich2_trap_log("Intel ICH2 Trap: A new trap was setted up on address 0x%x with the size of %d\n", addr, size);
io_trap_remap(trap->trap, trap_enabled, addr, size);
io_trap_remap(dev->trap, enable, addr, size);
}
static void
intel_ich2_trap_close(void *priv)
{
intel_ich2_trap_t *trap = (intel_ich2_trap_t *) priv;
io_trap_remove(trap->trap); // Remove the I/O Trap
free(trap);
intel_ich2_trap_t *dev = (intel_ich2_trap_t *) priv;
io_trap_remove(dev->trap); // Remove the I/O Trap
free(dev);
}
static void *
intel_ich2_trap_init(const device_t *info)
{
intel_ich2_trap_t *trap = (intel_ich2_trap_t *) malloc(sizeof(intel_ich2_trap_t));
memset(trap, 0, sizeof(intel_ich2_trap_t));
intel_ich2_trap_t *dev = (intel_ich2_trap_t *) malloc(sizeof(intel_ich2_trap_t));
memset(dev, 0, sizeof(intel_ich2_trap_t));
intel_ich2_trap_log("Intel ICH2 Trap: Starting a new Trap handler.");
return trap;
io_trap_add(intel_ich2_trap_kick, dev);
return dev;
}
const device_t intel_ich2_trap_device = {

View File

@@ -344,12 +344,11 @@ unknown_protocol:
}
/* Finish transfer. */
if (dev->local == SMBUS_INTEL_ICH2) {
/* ICH2 SMBus specific. Transfer on Byte command doesn't stop till their specific points. */
if (!dev->byte_rw)
i2c_stop(i2c_smbus, smbus_addr);
} else
i2c_stop(i2c_smbus, smbus_addr);
if (dev->local == SMBUS_INTEL_ICH2) // ICH2 SMBus specific. Transfer on Byte command doesn't stop till their specific points.
if (!dev->byte_rw)
i2c_stop(i2c_smbus, smbus_addr);
else
i2c_stop(i2c_smbus, smbus_addr);
}
break;

View File

@@ -15,6 +15,9 @@
*
* Copyright 2022 Tiseno100.
*/
/* Note: There's a TCO Timer too but for now it's of no use thus not implemented */
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
@@ -32,11 +35,9 @@
#include <86box/pit.h>
#include <86box/tco.h>
#ifdef ENABLE_TCO_LOG
int tco_do_log = ENABLE_TCO_LOG;
static void
tco_log(const char *fmt, ...)
{
@@ -68,7 +69,6 @@ tco_irq_update(tco_t *dev, uint16_t new_irq)
dev->tco_irq = new_irq;
}
void
tco_write(uint16_t addr, uint8_t val, tco_t *dev)
{
@@ -76,60 +76,60 @@ tco_write(uint16_t addr, uint8_t val, tco_t *dev)
tco_log("TCO: Write 0x%02x to Register 0x%02x\n", val, addr);
switch(addr) {
case 0x00:
dev->regs[addr] = val;
break;
case 0x00:
dev->regs[addr] = val;
break;
case 0x01:
dev->regs[addr] = val & 0x3f;
break;
case 0x01:
dev->regs[addr] = val & 0x3f;
break;
case 0x02: /* TCO Data in */
dev->regs[addr] = val;
dev->regs[0x04] |= 2;
smi_line = 1;
break;
case 0x02: /* TCO Data in */
dev->regs[addr] = val;
dev->regs[0x04] |= 2;
smi_line = 1;
break;
case 0x03: /* TCO Data out */
dev->regs[addr] = val;
dev->regs[0x04] |= 4;
picint(dev->tco_irq);
break;
case 0x03: /* TCO Data out */
dev->regs[addr] = val;
dev->regs[0x04] |= 4;
picint(1 << dev->tco_irq);
break;
case 0x04:
dev->regs[addr] &= 0x8f;
break;
dev->regs[addr] &= 0x8f;
break;
case 0x05:
dev->regs[addr] &= 0x1f;
break;
case 0x05:
dev->regs[addr] &= 0x1f;
break;
case 0x06:
dev->regs[addr] &= 0x07;
break;
case 0x06:
dev->regs[addr] &= 0x07;
break;
case 0x09:
if (val & 1) {
if (!nmi) /* If we're already on NMI */
nmi = 1;
case 0x09:
if (val & 1) {
if (!nmi) /* If we're already on NMI */
nmi_raise();
dev->regs[addr] = (dev->regs[addr] & 1) | val;
dev->regs[addr] &= val;
} else
dev->regs[addr] = 0x0f;
break;
dev->regs[addr] = (dev->regs[addr] & 1) | val;
dev->regs[addr] &= val;
} else
dev->regs[addr] = 0x0f;
break;
case 0x0a:
dev->regs[addr] = val & 0x06; // Intrusion Interrupt or SMI. We never get intruded so we never control it.
break;
case 0x0a:
dev->regs[addr] = val & 0x06; // Intrusion Interrupt or SMI. We never get intruded so we never control it.
break;
case 0x0c ... 0x0d:
dev->regs[addr] = val;
break;
case 0x0c ... 0x0d:
dev->regs[addr] = val;
break;
case 0x10:
dev->regs[addr] = val & 0x03;
break;
case 0x10:
dev->regs[addr] = val & 0x03;
break;
}
}
@@ -138,14 +138,12 @@ uint8_t
tco_read(uint16_t addr, tco_t *dev)
{
addr -= 0x60;
uint8_t ret = 0x00;
if (addr <= 0x10) {
tco_log("TCO: Read 0x%02x from Register 0x%02x\n", dev->regs[addr], addr);
ret = dev->regs[addr];
tco_log("TCO: Read 0x%02x from Register 0x%02x\n", dev->regs[addr], addr);
return dev->regs[addr];
}
return ret;
else return 0;
}
@@ -182,7 +180,6 @@ tco_init(const device_t *info)
return dev;
}
const device_t tco_device = {
.name = "Intel TCO",
.internal_name = "tco",