Add basic APM functionality for PIIX/PIIX3 and i430FX, i430VX, i430HX

and i440FX chipsets.
This commit is contained in:
SarahW 2020-11-01 14:46:56 +00:00
commit 38cee364d3
7 changed files with 233 additions and 8 deletions

View file

@ -106,6 +106,30 @@ void i430fx_write(int func, int addr, uint8_t val, void *priv)
i430fx_map(0xec000, 0x04000, val >> 4);
pclog("i430fx_write : PAM6 write %02X\n", val);
break;
case 0x72: /*SMRAM*/
pclog("Write SMRAM %02x\n", val);
val = (val & 0x78) | 2; /*SMRAM always at A0000-BFFFF*/
val |= (card_i430fx[0x72] & 0x10); /*D_LCK can not be cleared by software*/
if (val & 0x10) /*D_LCK locks D_OPEN and G_SMRAME*/
{
val &= ~0x48; /*D_OPEN is forced to 0, G_SMRAME is read only*/
val |= (card_i430fx[0x72] & 0x08);
}
if ((card_i430fx[0x72] ^ val) & 0x40)
{
if (val & 0x40) /*SMRAM enabled*/
{
pclog("Enable SMRAM\n");
mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
}
else
{
pclog("Disable SMRAM\n");
mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
}
}
break;
}
card_i430fx[addr] = val;
@ -119,6 +143,17 @@ uint8_t i430fx_read(int func, int addr, void *priv)
return card_i430fx[addr];
}
static void i430fx_smram_enable(void)
{
if (card_i430fx[0x72] & 8)
mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
}
static void i430fx_smram_disable(void)
{
if (card_i430fx[0x72] & 8)
mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
}
void i430fx_init()
{
pci_add_specific(0, i430fx_read, i430fx_write, NULL);
@ -141,6 +176,9 @@ void i430fx_init()
card_i430fx[0x72] = 0x02;
// card_i430fx[0x74] = 0x0e;
// card_i430fx[0x78] = 0x23;
smram_enable = i430fx_smram_enable;
smram_disable = i430fx_smram_disable;
}
void i430fx_reset()

View file

@ -106,6 +106,30 @@ void i430hx_write(int func, int addr, uint8_t val, void *priv)
i430hx_map(0xec000, 0x04000, val >> 4);
pclog("i430hx_write : PAM6 write %02X\n", val);
break;
case 0x72: /*SMRAM*/
pclog("Write SMRAM %02x\n", val);
val = (val & 0x78) | 2; /*SMRAM always at A0000-BFFFF*/
val |= (card_i430hx[0x72] & 0x10); /*D_LCK can not be cleared by software*/
if (val & 0x10) /*D_LCK locks D_OPEN and G_SMRAME*/
{
val &= ~0x48; /*D_OPEN is forced to 0, G_SMRAME is read only*/
val |= (card_i430hx[0x72] & 0x08);
}
if ((card_i430hx[0x72] ^ val) & 0x40)
{
if (val & 0x40) /*SMRAM enabled*/
{
pclog("Enable SMRAM\n");
mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
}
else
{
pclog("Disable SMRAM\n");
mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
}
}
break;
}
card_i430hx[addr] = val;
@ -119,7 +143,17 @@ uint8_t i430hx_read(int func, int addr, void *priv)
return card_i430hx[addr];
}
static void i430hx_smram_enable(void)
{
if (card_i430hx[0x72] & 8)
mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
}
static void i430hx_smram_disable(void)
{
if (card_i430hx[0x72] & 8)
mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
}
void i430hx_init()
{
pci_add_specific(0, i430hx_read, i430hx_write, NULL);
@ -141,6 +175,9 @@ void i430hx_init()
card_i430hx[0x64] = card_i430hx[0x5F] = 0x02;
card_i430hx[0x65] = card_i430hx[0x66] = card_i430hx[0x67] = 0x02;
card_i430hx[0x68] = 0x11;
smram_enable = i430hx_smram_enable;
smram_disable = i430hx_smram_disable;
}
void i430hx_reset()

View file

@ -105,6 +105,30 @@ void i430vx_write(int func, int addr, uint8_t val, void *priv)
i430vx_map(0xec000, 0x04000, val >> 4);
pclog("i430vx_write : PAM6 write %02X\n", val);
break;
case 0x72: /*SMRAM*/
pclog("Write SMRAM %02x\n", val);
val = (val & 0x78) | 2; /*SMRAM always at A0000-BFFFF*/
val |= (card_i430vx[0x72] & 0x10); /*D_LCK can not be cleared by software*/
if (val & 0x10) /*D_LCK locks D_OPEN and G_SMRAME*/
{
val &= ~0x48; /*D_OPEN is forced to 0, G_SMRAME is read only*/
val |= (card_i430vx[0x72] & 0x08);
}
if ((card_i430vx[0x72] ^ val) & 0x40)
{
if (val & 0x40) /*SMRAM enabled*/
{
pclog("Enable SMRAM\n");
mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
}
else
{
pclog("Disable SMRAM\n");
mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
}
}
break;
}
card_i430vx[addr] = val;
@ -118,7 +142,17 @@ uint8_t i430vx_read(int func, int addr, void *priv)
return card_i430vx[addr];
}
static void i430vx_smram_enable(void)
{
if (card_i430vx[0x72] & 8)
mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
}
static void i430vx_smram_disable(void)
{
if (card_i430vx[0x72] & 8)
mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
}
void i430vx_init()
{
pci_add_specific(0, i430vx_read, i430vx_write, NULL);
@ -141,6 +175,9 @@ void i430vx_init()
card_i430vx[0x72] = 0x02;
card_i430vx[0x74] = 0x0e;
card_i430vx[0x78] = 0x23;
smram_enable = i430vx_smram_enable;
smram_disable = i430vx_smram_disable;
}
void i430vx_reset()

View file

@ -106,6 +106,30 @@ void i440fx_write(int func, int addr, uint8_t val, void *priv)
i440fx_map(0xec000, 0x04000, val >> 4);
pclog("i440fx_write : PAM6 write %02X\n", val);
break;
case 0x72: /*SMRAM*/
pclog("Write SMRAM %02x\n", val);
val = (val & 0x78) | 2; /*SMRAM always at A0000-BFFFF*/
val |= (card_i440fx[0x72] & 0x10); /*D_LCK can not be cleared by software*/
if (val & 0x10) /*D_LCK locks D_OPEN and G_SMRAME*/
{
val &= ~0x48; /*D_OPEN is forced to 0, G_SMRAME is read only*/
val |= (card_i440fx[0x72] & 0x08);
}
if ((card_i440fx[0x72] ^ val) & 0x40)
{
if (val & 0x40) /*SMRAM enabled*/
{
pclog("Enable SMRAM\n");
mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
}
else
{
pclog("Disable SMRAM\n");
mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
}
}
break;
}
card_i440fx[addr] = val;
@ -119,6 +143,17 @@ uint8_t i440fx_read(int func, int addr, void *priv)
return card_i440fx[addr];
}
static void i440fx_smram_enable(void)
{
if (card_i440fx[0x72] & 8)
mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
}
static void i440fx_smram_disable(void)
{
if (card_i440fx[0x72] & 8)
mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
}
void i440fx_init()
{
pci_add_specific(0, i440fx_read, i440fx_write, NULL);
@ -137,6 +172,9 @@ void i440fx_init()
card_i440fx[0x60] = card_i440fx[0x61] = card_i440fx[0x62] = card_i440fx[0x63] = card_i440fx[0x64] = 0x01;
card_i440fx[0x71] = 0x10;
card_i440fx[0x72] = 0x02;
smram_enable = i440fx_smram_enable;
smram_disable = i440fx_smram_disable;
}
void i440fx_reset()

View file

@ -127,7 +127,7 @@ uint8_t endeavor_brdconfig(uint16_t port, void *p)
temp = 0x10;
else
temp = 0x10; // TODO: how are the overdrive processors configured?
return 0xe2 | temp;
return 0xe0 | temp;
}
return 0;
}

View file

@ -29,6 +29,12 @@ static sff_busmaster_t piix_busmaster[2];
static uint8_t piix_rc = 0;
static void (*piix_nb_reset)();
#define REG_SMIEN 0xa2
#define REG_SMIREQ 0xaa
#define SMIEN_APMC (1 << 7)
#define SMIREQ_RAPMC (1 << 7)
void piix_write(int func, int addr, uint8_t val, void *priv)
{
@ -139,6 +145,21 @@ void piix_write(int func, int addr, uint8_t val, void *priv)
else
pci_set_irq_routing(PCI_INTD, val & 0xf);
break;
case REG_SMIREQ:
if (piix.type <= TYPE_PIIX3)
{
card_piix[addr] &= val;
return;
}
break;
case REG_SMIREQ+1:
if (piix.type <= TYPE_PIIX3)
{
card_piix[addr] &= val;
return;
}
break;
}
card_piix[addr] = val;
}
@ -179,8 +200,11 @@ void piix_rc_write(uint16_t port, uint8_t val, void *p)
keyboard_at_reset(); /*Reset keyboard controller to reset system flag*/
ide_reset_devices();
piix.pm.timer_offset = tsc;
resetx86();
piix.pm.apmc = piix.pm.apms = 0;
}
resetx86();
else
softresetx86();
}
piix_rc = val & ~4;
@ -205,9 +229,53 @@ static void piix_92_write(uint16_t port, uint8_t val, void *p)
piix.port_92 = val;
}
void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_reset)())
static uint8_t piix_apm_read(uint16_t port, void *p)
{
piix_t *piix = (piix_t *)p;
uint8_t ret = 0xff;
switch (port)
{
case 0xb2:
ret = piix->pm.apmc;
break;
case 0xb3:
ret = piix->pm.apms;
break;
}
// pclog("piix_apm_read: port=%04x ret=%02x\n", port, ret);
return ret;
}
static void piix_apm_write(uint16_t port, uint8_t val, void *p)
{
piix_t *piix = (piix_t *)p;
// pclog("piix_apm_write: port=%04x val=%02x\n", port, val);
switch (port)
{
case 0xb2:
piix->pm.apmc = val;
if (card_piix[REG_SMIEN] & SMIEN_APMC)
{
card_piix[REG_SMIREQ] |= SMIREQ_RAPMC;
// pclog("APMC write causes SMI\n");
x86_smi_trigger();
}
break;
case 0xb3:
piix->pm.apms = val;
break;
}
}
static void piix_common_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_reset)())
{
memset(&piix, 0, sizeof(piix_t));
pci_add_specific(card, piix_read, piix_write, NULL);
memset(card_piix, 0, 256);
@ -263,6 +331,13 @@ void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_r
piix.type = TYPE_PIIX3;
}
void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_reset)())
{
piix_common_init(card, pci_a, pci_b, pci_c, pci_d, nb_reset);
io_sethandler(0x00b2, 0x0002, piix_apm_read, NULL, NULL, piix_apm_write, NULL, NULL, &piix);
}
void piix4_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_reset)())
{
piix_init(card, pci_a, pci_b, pci_c, pci_d, nb_reset);

View file

@ -291,7 +291,7 @@ static uint8_t piix_smbus_read(uint16_t port, void *p)
return ret;
}
static uint8_t piix_apm_read(uint16_t port, void *p)
static uint8_t piix4_apm_read(uint16_t port, void *p)
{
piix_t *piix = (piix_t *)p;
uint8_t ret = 0xff;
@ -309,7 +309,7 @@ static uint8_t piix_apm_read(uint16_t port, void *p)
// pclog("piix_apm_read: port=%04x ret=%02x\n", port, ret);
return ret;
}
static void piix_apm_write(uint16_t port, uint8_t val, void *p)
static void piix4_apm_write(uint16_t port, uint8_t val, void *p)
{
piix_t *piix = (piix_t *)p;
@ -413,5 +413,5 @@ void piix_pm_init(piix_t *piix)
piix->pm.timer_offset = 0;
piix->pm.gporeg = 0x7fffbfff;
io_sethandler(0x00b2, 0x0002, piix_apm_read, NULL, NULL, piix_apm_write, NULL, NULL, piix);
io_sethandler(0x00b2, 0x0002, piix4_apm_read, NULL, NULL, piix4_apm_write, NULL, NULL, piix);
}