Add basic APM functionality for PIIX/PIIX3 and i430FX, i430VX, i430HX
and i440FX chipsets.
This commit is contained in:
parent
93756d3f01
commit
38cee364d3
7 changed files with 233 additions and 8 deletions
38
src/i430fx.c
38
src/i430fx.c
|
|
@ -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()
|
||||
|
|
|
|||
39
src/i430hx.c
39
src/i430hx.c
|
|
@ -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()
|
||||
|
|
|
|||
39
src/i430vx.c
39
src/i430vx.c
|
|
@ -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()
|
||||
|
|
|
|||
38
src/i440fx.c
38
src/i440fx.c
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
81
src/piix.c
81
src/piix.c
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue