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
|
||||
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
|
||||
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);
|
||||
|
||||
port &= 0x0001;
|
||||
|
||||
if (port == 0x0000) {
|
||||
apm->cmd = val;
|
||||
if (apm->do_smi)
|
||||
dev->cmd = val;
|
||||
if (dev->do_smi)
|
||||
smi_line = 1;
|
||||
} else
|
||||
apm->stat = val;
|
||||
dev->stat = val;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
apm_in(uint16_t port, void *p)
|
||||
{
|
||||
apm_t *apm = (apm_t *) p;
|
||||
|
||||
apm_log("[%04X:%08X] APM read: %04X = FF\n", CS, cpu_state.pc, port);
|
||||
apm_t *dev = (apm_t *) p;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
port &= 0x0001;
|
||||
|
||||
if (port == 0x0000)
|
||||
return apm->cmd;
|
||||
ret = dev->cmd;
|
||||
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
|
||||
*apm_init(const device_t *info)
|
||||
{
|
||||
apm_t *apm = (apm_t *) malloc(sizeof(apm_t));
|
||||
memset(apm, 0, sizeof(apm_t));
|
||||
apm_t *dev = (apm_t *) malloc(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
|
||||
};
|
||||
|
||||
|
||||
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. */
|
||||
extern const device_t apm_device;
|
||||
extern const device_t apm_pci_device;
|
||||
|
||||
|
||||
/* 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
|
||||
}
|
||||
|
@@ -455,7 +455,7 @@ piix_write(int func, int addr, uint8_t val, void *priv)
|
||||
case 0xa0:
|
||||
if (dev->type < 4) {
|
||||
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) {
|
||||
case 0x00:
|
||||
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:
|
||||
if (dev->type < 4) {
|
||||
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;
|
||||
case 0xaa: case 0xac: case 0xae:
|
||||
@@ -1206,7 +1206,7 @@ static void
|
||||
} else
|
||||
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. */
|
||||
io_sethandler(0x00b2, 0x0001, NULL, NULL, NULL, piix_apm_out, NULL, NULL, dev);
|
||||
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] 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] 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 },
|
||||
|
||||
//430VX
|
||||
|
Reference in New Issue
Block a user