Implement APM on i430LX and SIO chipset.
This commit is contained in:
parent
38cee364d3
commit
82b1486f6b
2 changed files with 109 additions and 1 deletions
42
src/i430lx.c
42
src/i430lx.c
|
|
@ -6,6 +6,7 @@
|
|||
#include "keyboard_at.h"
|
||||
#include "mem.h"
|
||||
#include "pci.h"
|
||||
#include "sio.h"
|
||||
#include "x86.h"
|
||||
|
||||
#include "i430lx.h"
|
||||
|
|
@ -107,6 +108,30 @@ void i430lx_write(int func, int addr, uint8_t val, void *priv)
|
|||
i430lx_map(0xec000, 0x04000, val >> 4);
|
||||
pclog("i430lx_write : PAM6 write %02X\n", val);
|
||||
break;
|
||||
|
||||
case 0x72: /*SMRAM*/
|
||||
pclog("Write SMRAM %02x\n", val);
|
||||
val = (val & 0x38) | 2; /*SMRAM always at A0000-BFFFF*/
|
||||
val |= (card_i430lx[0x72] & 0x08); /*D_LCK can not be cleared by software*/
|
||||
if (val & 0x08) /*D_LCK locks D_OPEN*/
|
||||
{
|
||||
val &= ~0x20; /*D_OPEN is forced to 0*/
|
||||
}
|
||||
val |= (card_i430lx[0x72] & 0x08);
|
||||
if ((card_i430lx[0x72] ^ val) & 0x20)
|
||||
{
|
||||
if (val & 0x20) /*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_i430lx[addr] = val;
|
||||
|
|
@ -134,15 +159,27 @@ void i430lx_trc_write(uint16_t port, uint8_t val, void *p)
|
|||
if (val & 2) /*Hard reset*/
|
||||
{
|
||||
i430lx_write(0, 0x59, 0xf, NULL); /*Should reset all PCI devices, but just set PAM0 to point to ROM for now*/
|
||||
card_i430lx[0x72] = 0; /*Also clear SMRAM register so BIOS will relocate SMBASE*/
|
||||
keyboard_at_reset(); /*Reset keyboard controller to reset system flag*/
|
||||
ide_reset_devices();
|
||||
resetx86();
|
||||
}
|
||||
resetx86();
|
||||
else
|
||||
softresetx86();
|
||||
}
|
||||
|
||||
trc = val;
|
||||
}
|
||||
|
||||
static void i430lx_smram_enable(void)
|
||||
{
|
||||
mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
}
|
||||
static void i430lx_smram_disable(void)
|
||||
{
|
||||
mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
}
|
||||
|
||||
void i430lx_init()
|
||||
{
|
||||
pci_add_specific(0, i430lx_read, i430lx_write, NULL);
|
||||
|
|
@ -168,4 +205,7 @@ void i430lx_init()
|
|||
// card_i430lx[0x78] = 0x23;
|
||||
|
||||
io_sethandler(0x0cf9, 0x0001, i430lx_trc_read, NULL, NULL, i430lx_trc_write, NULL, NULL, NULL);
|
||||
|
||||
smram_enable = i430lx_smram_enable;
|
||||
smram_disable = i430lx_smram_disable;
|
||||
}
|
||||
|
|
|
|||
68
src/sio.c
68
src/sio.c
|
|
@ -8,9 +8,23 @@
|
|||
|
||||
#include "sio.h"
|
||||
|
||||
typedef struct sio_t
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t apmc, apms;
|
||||
} pm;
|
||||
} sio_t;
|
||||
static sio_t sio;
|
||||
static uint8_t card_sio[256];
|
||||
//static int pci_cards_ids[4];
|
||||
|
||||
#define REG_SMIEN 0xa2
|
||||
#define REG_SMIREQ 0xaa
|
||||
|
||||
#define SMIEN_APMC (1 << 7)
|
||||
#define SMIREQ_RAPMC (1 << 7)
|
||||
|
||||
void sio_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
// pclog("sio_write: func=%d addr=%02x val=%02x %04x:%08x\n", func, addr, val, CS, cpu_state.pc);
|
||||
|
|
@ -70,6 +84,13 @@ void sio_write(int func, int addr, uint8_t val, void *priv)
|
|||
else
|
||||
pci_set_irq_routing(PCI_INTD, val & 0xf);
|
||||
break;
|
||||
|
||||
case REG_SMIREQ:
|
||||
card_sio[addr] &= val;
|
||||
return;
|
||||
case REG_SMIREQ+1:
|
||||
card_sio[addr] &= val;
|
||||
return;
|
||||
}
|
||||
card_sio[addr] = val;
|
||||
}
|
||||
|
|
@ -83,8 +104,53 @@ uint8_t sio_read(int func, int addr, void *priv)
|
|||
return card_sio[addr];
|
||||
}
|
||||
|
||||
static uint8_t sio_apm_read(uint16_t port, void *p)
|
||||
{
|
||||
sio_t *sio = (sio_t *)p;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (port)
|
||||
{
|
||||
case 0xb2:
|
||||
ret = sio->pm.apmc;
|
||||
break;
|
||||
|
||||
case 0xb3:
|
||||
ret = sio->pm.apms;
|
||||
break;
|
||||
}
|
||||
// pclog("sio_apm_read: port=%04x ret=%02x\n", port, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sio_apm_write(uint16_t port, uint8_t val, void *p)
|
||||
{
|
||||
sio_t *sio = (sio_t *)p;
|
||||
|
||||
// pclog("sio_apm_write: port=%04x val=%02x\n", port, val);
|
||||
|
||||
switch (port)
|
||||
{
|
||||
case 0xb2:
|
||||
sio->pm.apmc = val;
|
||||
if (card_sio[REG_SMIEN] & SMIEN_APMC)
|
||||
{
|
||||
card_sio[REG_SMIREQ] |= SMIREQ_RAPMC;
|
||||
// pclog("APMC write causes SMI\n");
|
||||
x86_smi_trigger();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xb3:
|
||||
sio->pm.apms = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void sio_init(int card, int pci_a, int pci_b, int pci_c, int pci_d)
|
||||
{
|
||||
memset(&sio, 0, sizeof(sio_t));
|
||||
|
||||
pci_add_specific(card, sio_read, sio_write, NULL);
|
||||
|
||||
memset(card_sio, 0, 256);
|
||||
|
|
@ -116,4 +182,6 @@ void sio_init(int card, int pci_a, int pci_b, int pci_c, int pci_d)
|
|||
pci_set_card_routing(pci_c, PCI_INTC);
|
||||
if (pci_d)
|
||||
pci_set_card_routing(pci_d, PCI_INTD);
|
||||
|
||||
io_sethandler(0x00b2, 0x0002, sio_apm_read, NULL, NULL, sio_apm_write, NULL, NULL, &sio);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue