Added a PCI APM device that has a reset function that clears and status back to 0x00 on device reset, fixes soft reset hangs on the ASUS P/I-P55TVP4, and also made it clear that the TC430HX is Intel.
This commit is contained in:
57
src/apm.c
57
src/apm.c
@@ -49,43 +49,55 @@ apm_log(const char *fmt, ...)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
apm_set_do_smi(apm_t *apm, uint8_t do_smi)
|
apm_set_do_smi(apm_t *dev, uint8_t do_smi)
|
||||||
{
|
{
|
||||||
apm->do_smi = do_smi;
|
dev->do_smi = do_smi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
apm_out(uint16_t port, uint8_t val, void *p)
|
apm_out(uint16_t port, uint8_t val, void *p)
|
||||||
{
|
{
|
||||||
apm_t *apm = (apm_t *) p;
|
apm_t *dev = (apm_t *) p;
|
||||||
|
|
||||||
apm_log("[%04X:%08X] APM write: %04X = %02X (BX = %04X, CX = %04X)\n", CS, cpu_state.pc, port, val, BX, CX);
|
apm_log("[%04X:%08X] APM write: %04X = %02X (BX = %04X, CX = %04X)\n", CS, cpu_state.pc, port, val, BX, CX);
|
||||||
|
|
||||||
port &= 0x0001;
|
port &= 0x0001;
|
||||||
|
|
||||||
if (port == 0x0000) {
|
if (port == 0x0000) {
|
||||||
apm->cmd = val;
|
dev->cmd = val;
|
||||||
if (apm->do_smi)
|
if (dev->do_smi)
|
||||||
smi_line = 1;
|
smi_line = 1;
|
||||||
} else
|
} else
|
||||||
apm->stat = val;
|
dev->stat = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint8_t
|
static uint8_t
|
||||||
apm_in(uint16_t port, void *p)
|
apm_in(uint16_t port, void *p)
|
||||||
{
|
{
|
||||||
apm_t *apm = (apm_t *) p;
|
apm_t *dev = (apm_t *) p;
|
||||||
|
uint8_t ret = 0xff;
|
||||||
apm_log("[%04X:%08X] APM read: %04X = FF\n", CS, cpu_state.pc, port);
|
|
||||||
|
|
||||||
port &= 0x0001;
|
port &= 0x0001;
|
||||||
|
|
||||||
if (port == 0x0000)
|
if (port == 0x0000)
|
||||||
return apm->cmd;
|
ret = dev->cmd;
|
||||||
else
|
else
|
||||||
return apm->stat;
|
ret = dev->stat;
|
||||||
|
|
||||||
|
apm_log("[%04X:%08X] APM read: %04X = %02X\n", CS, cpu_state.pc, port, ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
apm_reset(void *p)
|
||||||
|
{
|
||||||
|
apm_t *dev = (apm_t *)p;
|
||||||
|
|
||||||
|
dev->cmd = dev->stat = 0x00;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -101,12 +113,12 @@ apm_close(void *p)
|
|||||||
static void
|
static void
|
||||||
*apm_init(const device_t *info)
|
*apm_init(const device_t *info)
|
||||||
{
|
{
|
||||||
apm_t *apm = (apm_t *) malloc(sizeof(apm_t));
|
apm_t *dev = (apm_t *) malloc(sizeof(apm_t));
|
||||||
memset(apm, 0, sizeof(apm_t));
|
memset(dev, 0, sizeof(apm_t));
|
||||||
|
|
||||||
io_sethandler(0x00b2, 0x0002, apm_in, NULL, NULL, apm_out, NULL, NULL, apm);
|
io_sethandler(0x00b2, 0x0002, apm_in, NULL, NULL, apm_out, NULL, NULL, dev);
|
||||||
|
|
||||||
return apm;
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -123,3 +135,18 @@ const device_t apm_device =
|
|||||||
NULL,
|
NULL,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const device_t apm_pci_device =
|
||||||
|
{
|
||||||
|
"Advanced Power Management (PCI)",
|
||||||
|
DEVICE_PCI,
|
||||||
|
0,
|
||||||
|
apm_init,
|
||||||
|
apm_close,
|
||||||
|
apm_reset,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
@@ -38,10 +38,11 @@ typedef struct
|
|||||||
|
|
||||||
/* Global variables. */
|
/* Global variables. */
|
||||||
extern const device_t apm_device;
|
extern const device_t apm_device;
|
||||||
|
extern const device_t apm_pci_device;
|
||||||
|
|
||||||
|
|
||||||
/* Functions. */
|
/* Functions. */
|
||||||
extern void apm_set_do_smi(apm_t *apm, uint8_t do_smi);
|
extern void apm_set_do_smi(apm_t *dev, uint8_t do_smi);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@@ -455,7 +455,7 @@ piix_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
case 0xa0:
|
case 0xa0:
|
||||||
if (dev->type < 4) {
|
if (dev->type < 4) {
|
||||||
fregs[addr] = val & 0x1f;
|
fregs[addr] = val & 0x1f;
|
||||||
apm_set_do_smi(dev->apm, (val & 0x01) | (fregs[0xa2] & 0x80));
|
apm_set_do_smi(dev->apm, !!(val & 0x01) && !!(fregs[0xa2] & 0x80));
|
||||||
switch ((val & 0x18) >> 3) {
|
switch ((val & 0x18) >> 3) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
dev->fast_off_period = PCICLK * 32768.0 * 60000.0;
|
dev->fast_off_period = PCICLK * 32768.0 * 60000.0;
|
||||||
@@ -480,7 +480,7 @@ piix_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
case 0xa2:
|
case 0xa2:
|
||||||
if (dev->type < 4) {
|
if (dev->type < 4) {
|
||||||
fregs[addr] = val & 0xff;
|
fregs[addr] = val & 0xff;
|
||||||
apm_set_do_smi(dev->apm, (fregs[0xa0] & 0x01) | (val & 0x80));
|
apm_set_do_smi(dev->apm, !!(fregs[0xa0] & 0x01) && !!(val & 0x80));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0xaa: case 0xac: case 0xae:
|
case 0xaa: case 0xac: case 0xae:
|
||||||
@@ -1206,7 +1206,7 @@ static void
|
|||||||
} else
|
} else
|
||||||
cpu_fast_off_val = cpu_fast_off_count = 0;
|
cpu_fast_off_val = cpu_fast_off_count = 0;
|
||||||
|
|
||||||
dev->apm = device_add(&apm_device);
|
dev->apm = device_add(&apm_pci_device);
|
||||||
/* APM intercept handler to update PIIX/PIIX3 and PIIX4/4E/SMSC ACPI SMI status on APM SMI. */
|
/* APM intercept handler to update PIIX/PIIX3 and PIIX4/4E/SMSC ACPI SMI status on APM SMI. */
|
||||||
io_sethandler(0x00b2, 0x0001, NULL, NULL, NULL, piix_apm_out, NULL, NULL, dev);
|
io_sethandler(0x00b2, 0x0001, NULL, NULL, NULL, piix_apm_out, NULL, NULL, dev);
|
||||||
dev->port_92 = device_add(&port_92_pci_device);
|
dev->port_92 = device_add(&port_92_pci_device);
|
||||||
|
@@ -243,7 +243,7 @@ const machine_t machines[] = {
|
|||||||
{ "[Socket 7 HX] Acer V35n", "acerv35n", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerv35n_init, NULL },
|
{ "[Socket 7 HX] Acer V35n", "acerv35n", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerv35n_init, NULL },
|
||||||
{ "[Socket 7 HX] ASUS P/I-P55T2P4", "p55t2p4", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 127, machine_at_p55t2p4_init, NULL },
|
{ "[Socket 7 HX] ASUS P/I-P55T2P4", "p55t2p4", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 127, machine_at_p55t2p4_init, NULL },
|
||||||
{ "[Socket 7 HX] Micronics M7S-Hi", "m7shi", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 511, machine_at_m7shi_init, NULL },
|
{ "[Socket 7 HX] Micronics M7S-Hi", "m7shi", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 511, machine_at_m7shi_init, NULL },
|
||||||
{ "[Socket 7 HX] TC430HX", "tc430hx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 255, machine_at_tc430hx_init, NULL },
|
{ "[Socket 7 HX] Intel TC430HX", "tc430hx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 255, machine_at_tc430hx_init, NULL },
|
||||||
{ "[Socket 7 HX] Toshiba Equium 5200D", "equium5200", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_equium5200_init, NULL },
|
{ "[Socket 7 HX] Toshiba Equium 5200D", "equium5200", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_equium5200_init, NULL },
|
||||||
|
|
||||||
//430VX
|
//430VX
|
||||||
|
@@ -710,7 +710,6 @@ void
|
|||||||
trc_write(uint16_t port, uint8_t val, void *priv)
|
trc_write(uint16_t port, uint8_t val, void *priv)
|
||||||
{
|
{
|
||||||
pci_log("TRC Write: %02X\n", val);
|
pci_log("TRC Write: %02X\n", val);
|
||||||
pci_log("TRC Write: %02X\n", val);
|
|
||||||
|
|
||||||
if (!(trc_reg & 4) && (val & 4))
|
if (!(trc_reg & 4) && (val & 4))
|
||||||
trc_reset(val);
|
trc_reset(val);
|
||||||
|
Reference in New Issue
Block a user