diff --git a/src/i430fx.c b/src/i430fx.c index a562447..678c824 100644 --- a/src/i430fx.c +++ b/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() diff --git a/src/i430hx.c b/src/i430hx.c index 0871ca9..466b002 100644 --- a/src/i430hx.c +++ b/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() diff --git a/src/i430vx.c b/src/i430vx.c index 5d97d23..fde2258 100644 --- a/src/i430vx.c +++ b/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() diff --git a/src/i440fx.c b/src/i440fx.c index c95c79c..87d1dfe 100644 --- a/src/i440fx.c +++ b/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() diff --git a/src/intel.c b/src/intel.c index 2010cc3..3d66644 100644 --- a/src/intel.c +++ b/src/intel.c @@ -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; } diff --git a/src/piix.c b/src/piix.c index 184c748..35eebe2 100644 --- a/src/piix.c +++ b/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); diff --git a/src/piix_pm.c b/src/piix_pm.c index a3947b7..e55766f 100644 --- a/src/piix_pm.c +++ b/src/piix_pm.c @@ -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); }