Added the SMC FDC37C931APM Super I/O chip.
This commit is contained in:
311
src/acpi.c
311
src/acpi.c
@@ -63,17 +63,19 @@ acpi_update_irq(void *priv)
|
|||||||
int sci_level;
|
int sci_level;
|
||||||
|
|
||||||
sci_level = (dev->regs.pmsts & dev->regs.pmen) & (RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN);
|
sci_level = (dev->regs.pmsts & dev->regs.pmen) & (RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN);
|
||||||
|
if (dev->vendor == VEN_SMC)
|
||||||
|
sci_level |= (dev->regs.pmsts & BM_STS);
|
||||||
|
|
||||||
if (sci_level) {
|
if (sci_level) {
|
||||||
if (dev->regs.irq_mode == 1)
|
if (dev->irq_mode == 1)
|
||||||
pci_set_irq(dev->regs.slot, dev->regs.irq_pin);
|
pci_set_irq(dev->slot, dev->irq_pin);
|
||||||
else
|
else
|
||||||
picintlevel(1 << 9);
|
picintlevel(1 << dev->irq_line);
|
||||||
} else {
|
} else {
|
||||||
if (dev->regs.irq_mode == 1)
|
if (dev->irq_mode == 1)
|
||||||
pci_clear_irq(dev->regs.slot, dev->regs.irq_pin);
|
pci_clear_irq(dev->slot, dev->irq_pin);
|
||||||
else
|
else
|
||||||
picintc(1 << 9);
|
picintc(1 << dev->irq_line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,12 +90,15 @@ acpi_raise_smi(void *priv)
|
|||||||
smi_line = 1;
|
smi_line = 1;
|
||||||
dev->regs.smi_active = 1;
|
dev->regs.smi_active = 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (dev->vendor == VEN_INTEL) {
|
||||||
if (dev->regs.glbctl & 0x01) {
|
if (dev->regs.glbctl & 0x01) {
|
||||||
smi_line = 1;
|
smi_line = 1;
|
||||||
/* Clear bit 16 of GLBCTL. */
|
/* Clear bit 16 of GLBCTL. */
|
||||||
dev->regs.glbctl &= ~0x00010000;
|
dev->regs.glbctl &= ~0x00010000;
|
||||||
}
|
}
|
||||||
|
} else if (dev->vendor == VEN_SMC) {
|
||||||
|
if (dev->regs.glbctl & 0x01)
|
||||||
|
smi_line = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,17 +312,67 @@ acpi_reg_read_via(int size, uint16_t addr, void *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
acpi_reg_read_smc(int size, uint16_t addr, void *p)
|
||||||
|
{
|
||||||
|
uint32_t ret = 0x00000000;
|
||||||
|
|
||||||
|
addr &= 0x0f;
|
||||||
|
|
||||||
|
ret = acpi_reg_read_common_regs(size, addr, p);
|
||||||
|
|
||||||
|
acpi_log("(%i) ACPI Read (%i) %02X: %02X\n", in_smm, size, addr, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
acpi_aux_reg_read_smc(int size, uint16_t addr, void *p)
|
||||||
|
{
|
||||||
|
acpi_t *dev = (acpi_t *) p;
|
||||||
|
uint32_t ret = 0x00000000;
|
||||||
|
int shift16;
|
||||||
|
|
||||||
|
addr &= 0x07;
|
||||||
|
shift16 = (addr & 1) << 3;
|
||||||
|
|
||||||
|
switch (addr) {
|
||||||
|
case 0x00: case 0x01:
|
||||||
|
/* SCI Status Register */
|
||||||
|
ret = (dev->regs.pcntrl >> shift16) & 0xff;
|
||||||
|
break;
|
||||||
|
case 0x02: case 0x03:
|
||||||
|
/* SCI Enable Register */
|
||||||
|
ret = (dev->regs.gpscien >> shift16) & 0xff;
|
||||||
|
break;
|
||||||
|
case 0x04: case 0x05:
|
||||||
|
/* Miscellaneous Status Register */
|
||||||
|
ret = (dev->regs.glbsts >> shift16) & 0xff;
|
||||||
|
break;
|
||||||
|
case 0x06:
|
||||||
|
/* Miscellaneous Enable Register */
|
||||||
|
ret = dev->regs.glben & 0xff;
|
||||||
|
break;
|
||||||
|
case 0x07:
|
||||||
|
/* Miscellaneous Control Register */
|
||||||
|
ret = dev->regs.glbctl & 0xff;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
acpi_log("(%i) ACPI Read (%i) %02X: %02X\n", in_smm, size, addr, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
acpi_reg_write_common_regs(int size, uint16_t addr, uint8_t val, void *p)
|
acpi_reg_write_common_regs(int size, uint16_t addr, uint8_t val, void *p)
|
||||||
{
|
{
|
||||||
acpi_t *dev = (acpi_t *) p;
|
acpi_t *dev = (acpi_t *) p;
|
||||||
int shift16, shift32;
|
int shift16, sus_typ;
|
||||||
int sus_typ;
|
|
||||||
|
|
||||||
addr &= 0x3f;
|
addr &= 0x3f;
|
||||||
acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val);
|
acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val);
|
||||||
shift16 = (addr & 1) << 3;
|
shift16 = (addr & 1) << 3;
|
||||||
shift32 = (addr & 3) << 3;
|
|
||||||
|
|
||||||
switch (addr) {
|
switch (addr) {
|
||||||
case 0x00: case 0x01:
|
case 0x00: case 0x01:
|
||||||
@@ -377,7 +432,6 @@ acpi_reg_write_intel(int size, uint16_t addr, uint8_t val, void *p)
|
|||||||
{
|
{
|
||||||
acpi_t *dev = (acpi_t *) p;
|
acpi_t *dev = (acpi_t *) p;
|
||||||
int shift16, shift32;
|
int shift16, shift32;
|
||||||
int sus_typ;
|
|
||||||
|
|
||||||
addr &= 0x3f;
|
addr &= 0x3f;
|
||||||
acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val);
|
acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val);
|
||||||
@@ -431,7 +485,9 @@ acpi_reg_write_intel(int size, uint16_t addr, uint8_t val, void *p)
|
|||||||
default:
|
default:
|
||||||
acpi_reg_write_common_regs(size, addr, val, p);
|
acpi_reg_write_common_regs(size, addr, val, p);
|
||||||
/* Setting GBL_RLS also sets BIOS_STS and generates SMI. */
|
/* Setting GBL_RLS also sets BIOS_STS and generates SMI. */
|
||||||
if ((addr == 0x04) && (dev->regs.pmcntrl & 0x0004)) {
|
if ((addr == 0x00) && !(dev->regs.pmsts & 0x20))
|
||||||
|
dev->regs.glbctl &= ~0x0002;
|
||||||
|
else if ((addr == 0x04) && (dev->regs.pmcntrl & 0x0004)) {
|
||||||
dev->regs.glbsts |= 0x01;
|
dev->regs.glbsts |= 0x01;
|
||||||
if (dev->regs.glben & 0x02)
|
if (dev->regs.glben & 0x02)
|
||||||
acpi_raise_smi(dev);
|
acpi_raise_smi(dev);
|
||||||
@@ -446,7 +502,6 @@ acpi_reg_write_via(int size, uint16_t addr, uint8_t val, void *p)
|
|||||||
{
|
{
|
||||||
acpi_t *dev = (acpi_t *) p;
|
acpi_t *dev = (acpi_t *) p;
|
||||||
int shift16, shift32;
|
int shift16, shift32;
|
||||||
int sus_typ;
|
|
||||||
|
|
||||||
addr &= 0xff;
|
addr &= 0xff;
|
||||||
acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val);
|
acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val);
|
||||||
@@ -549,6 +604,72 @@ acpi_reg_write_via(int size, uint16_t addr, uint8_t val, void *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
acpi_reg_write_smc(int size, uint16_t addr, uint8_t val, void *p)
|
||||||
|
{
|
||||||
|
acpi_t *dev = (acpi_t *) p;
|
||||||
|
|
||||||
|
addr &= 0x0f;
|
||||||
|
acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val);
|
||||||
|
|
||||||
|
acpi_reg_write_common_regs(size, addr, val, p);
|
||||||
|
/* Setting GBL_RLS also sets BIOS_STS and generates SMI. */
|
||||||
|
if ((addr == 0x00) && !(dev->regs.pmsts & 0x20))
|
||||||
|
dev->regs.glbctl &= ~0x0001;
|
||||||
|
else if ((addr == 0x04) && (dev->regs.pmcntrl & 0x0004)) {
|
||||||
|
dev->regs.glbsts |= 0x01;
|
||||||
|
if (dev->regs.glben & 0x01)
|
||||||
|
acpi_raise_smi(dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
acpi_aux_reg_write_smc(int size, uint16_t addr, uint8_t val, void *p)
|
||||||
|
{
|
||||||
|
acpi_t *dev = (acpi_t *) p;
|
||||||
|
int shift16;
|
||||||
|
|
||||||
|
addr &= 0x07;
|
||||||
|
acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val);
|
||||||
|
shift16 = (addr & 1) << 3;
|
||||||
|
|
||||||
|
switch (addr) {
|
||||||
|
case 0x00: case 0x01:
|
||||||
|
/* SCI Status Register */
|
||||||
|
dev->regs.gpscists &= ~((val << shift16) & 0x000c);
|
||||||
|
break;
|
||||||
|
case 0x02: case 0x03:
|
||||||
|
/* SCI Enable Register */
|
||||||
|
dev->regs.gpscien = ((dev->regs.gpscien & ~(0xff << shift16)) | (val << shift16)) & 0x3fff;
|
||||||
|
break;
|
||||||
|
case 0x04: case 0x05:
|
||||||
|
/* Miscellanous Status Register */
|
||||||
|
dev->regs.glbsts &= ~((val << shift16) & 0x001f);
|
||||||
|
break;
|
||||||
|
case 0x06:
|
||||||
|
/* Miscellaneous Enable Register */
|
||||||
|
dev->regs.glben = (uint16_t) (val & 0x03);
|
||||||
|
break;
|
||||||
|
case 0x07:
|
||||||
|
/* Miscellaneous Control Register */
|
||||||
|
dev->regs.glbctl = (uint16_t) (val & 0x03);
|
||||||
|
/* Setting BIOS_RLS also sets GBL_STS and generates SMI. */
|
||||||
|
if (dev->regs.glbctl & 0x0001) {
|
||||||
|
dev->regs.pmsts |= 0x20;
|
||||||
|
if (dev->regs.pmen & 0x20)
|
||||||
|
acpi_update_irq(dev);
|
||||||
|
}
|
||||||
|
if (dev->regs.glbctl & 0x0002) {
|
||||||
|
dev->regs.pmsts |= 0x10;
|
||||||
|
if (dev->regs.pmcntrl & 0x02)
|
||||||
|
acpi_update_irq(dev);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
acpi_reg_read_common(int size, uint16_t addr, void *p)
|
acpi_reg_read_common(int size, uint16_t addr, void *p)
|
||||||
{
|
{
|
||||||
@@ -557,8 +678,10 @@ acpi_reg_read_common(int size, uint16_t addr, void *p)
|
|||||||
|
|
||||||
if (dev->vendor == VEN_VIA)
|
if (dev->vendor == VEN_VIA)
|
||||||
ret = acpi_reg_read_via(size, addr, p);
|
ret = acpi_reg_read_via(size, addr, p);
|
||||||
else
|
else if (dev->vendor == VEN_INTEL)
|
||||||
ret = acpi_reg_read_intel(size, addr, p);
|
ret = acpi_reg_read_intel(size, addr, p);
|
||||||
|
else if (dev->vendor == VEN_SMC)
|
||||||
|
ret = acpi_reg_read_smc(size, addr, p);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -571,8 +694,33 @@ acpi_reg_write_common(int size, uint16_t addr, uint8_t val, void *p)
|
|||||||
|
|
||||||
if (dev->vendor == VEN_VIA)
|
if (dev->vendor == VEN_VIA)
|
||||||
acpi_reg_write_via(size, addr, val, p);
|
acpi_reg_write_via(size, addr, val, p);
|
||||||
else
|
else if (dev->vendor == VEN_INTEL)
|
||||||
acpi_reg_write_intel(size, addr, val, p);
|
acpi_reg_write_intel(size, addr, val, p);
|
||||||
|
else if (dev->vendor == VEN_SMC)
|
||||||
|
acpi_reg_write_smc(size, addr, val, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
acpi_aux_reg_read_common(int size, uint16_t addr, void *p)
|
||||||
|
{
|
||||||
|
acpi_t *dev = (acpi_t *) p;
|
||||||
|
uint8_t ret = 0xff;
|
||||||
|
|
||||||
|
if (dev->vendor == VEN_SMC)
|
||||||
|
ret = acpi_aux_reg_read_smc(size, addr, p);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
acpi_aux_reg_write_common(int size, uint16_t addr, uint8_t val, void *p)
|
||||||
|
{
|
||||||
|
acpi_t *dev = (acpi_t *) p;
|
||||||
|
|
||||||
|
if (dev->vendor == VEN_SMC)
|
||||||
|
acpi_aux_reg_write_smc(size, addr, val, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -617,6 +765,47 @@ acpi_reg_read(uint16_t addr, void *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
acpi_aux_read_readl(uint16_t addr, void *p)
|
||||||
|
{
|
||||||
|
uint32_t ret = 0x00000000;
|
||||||
|
|
||||||
|
ret = acpi_aux_reg_read_common(4, addr, p);
|
||||||
|
ret |= (acpi_aux_reg_read_common(4, addr + 1, p) << 8);
|
||||||
|
ret |= (acpi_aux_reg_read_common(4, addr + 2, p) << 16);
|
||||||
|
ret |= (acpi_aux_reg_read_common(4, addr + 3, p) << 24);
|
||||||
|
|
||||||
|
acpi_log("ACPI: Read L %08X from %04X\n", ret, addr);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint16_t
|
||||||
|
acpi_aux_read_readw(uint16_t addr, void *p)
|
||||||
|
{
|
||||||
|
uint16_t ret = 0x0000;
|
||||||
|
|
||||||
|
ret = acpi_aux_reg_read_common(2, addr, p);
|
||||||
|
ret |= (acpi_aux_reg_read_common(2, addr + 1, p) << 8);
|
||||||
|
|
||||||
|
acpi_log("ACPI: Read W %08X from %04X\n", ret, addr);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint8_t
|
||||||
|
acpi_aux_read_read(uint16_t addr, void *p)
|
||||||
|
{
|
||||||
|
uint8_t ret = 0x00;
|
||||||
|
|
||||||
|
ret = acpi_aux_reg_read_common(1, addr, p);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
acpi_reg_writel(uint16_t addr, uint32_t val, void *p)
|
acpi_reg_writel(uint16_t addr, uint32_t val, void *p)
|
||||||
{
|
{
|
||||||
@@ -642,25 +831,71 @@ acpi_reg_write(uint16_t addr, uint8_t val, void *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
acpi_aux_reg_writel(uint16_t addr, uint32_t val, void *p)
|
||||||
|
{
|
||||||
|
acpi_aux_reg_write_common(4, addr, val & 0xff, p);
|
||||||
|
acpi_aux_reg_write_common(4, addr + 1, (val >> 8) & 0xff, p);
|
||||||
|
acpi_aux_reg_write_common(4, addr + 1, (val >> 16) & 0xff, p);
|
||||||
|
acpi_aux_reg_write_common(4, addr + 1, (val >> 24) & 0xff, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
acpi_aux_reg_writew(uint16_t addr, uint16_t val, void *p)
|
||||||
|
{
|
||||||
|
acpi_aux_reg_write_common(2, addr, val & 0xff, p);
|
||||||
|
acpi_aux_reg_write_common(2, addr + 1, (val >> 8) & 0xff, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
acpi_aux_reg_write(uint16_t addr, uint8_t val, void *p)
|
||||||
|
{
|
||||||
|
acpi_aux_reg_write_common(1, addr, val, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
acpi_update_io_mapping(acpi_t *dev, uint32_t base, int chipset_en)
|
acpi_update_io_mapping(acpi_t *dev, uint32_t base, int chipset_en)
|
||||||
{
|
{
|
||||||
if (dev->regs.io_base != 0x0000) {
|
int size = (dev->vendor == VEN_SMC) ? 0x10 : 0x40;
|
||||||
io_removehandler(dev->regs.io_base, 0x40,
|
|
||||||
|
if (dev->io_base != 0x0000) {
|
||||||
|
io_removehandler(dev->io_base, size,
|
||||||
acpi_reg_read, acpi_reg_readw, acpi_reg_readl,
|
acpi_reg_read, acpi_reg_readw, acpi_reg_readl,
|
||||||
acpi_reg_write, acpi_reg_writew, acpi_reg_writel, dev);
|
acpi_reg_write, acpi_reg_writew, acpi_reg_writel, dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->regs.io_base = base;
|
dev->io_base = base;
|
||||||
|
|
||||||
if (chipset_en && (dev->regs.io_base != 0x0000)) {
|
if (chipset_en && (dev->io_base != 0x0000)) {
|
||||||
io_sethandler(dev->regs.io_base, 0x40,
|
io_sethandler(dev->io_base, size,
|
||||||
acpi_reg_read, acpi_reg_readw, acpi_reg_readl,
|
acpi_reg_read, acpi_reg_readw, acpi_reg_readl,
|
||||||
acpi_reg_write, acpi_reg_writew, acpi_reg_writel, dev);
|
acpi_reg_write, acpi_reg_writew, acpi_reg_writel, dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
acpi_update_aux_io_mapping(acpi_t *dev, uint32_t base, int chipset_en)
|
||||||
|
{
|
||||||
|
if (dev->aux_io_base != 0x0000) {
|
||||||
|
io_removehandler(dev->aux_io_base, 0x08,
|
||||||
|
acpi_aux_read_read, acpi_aux_read_readw, acpi_aux_read_readl,
|
||||||
|
acpi_aux_reg_write, acpi_aux_reg_writew, acpi_aux_reg_writel, dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
dev->aux_io_base = base;
|
||||||
|
|
||||||
|
if (chipset_en && (dev->aux_io_base != 0x0000)) {
|
||||||
|
io_sethandler(dev->aux_io_base, 0x08,
|
||||||
|
acpi_aux_read_read, acpi_aux_read_readw, acpi_aux_read_readl,
|
||||||
|
acpi_aux_reg_write, acpi_aux_reg_writew, acpi_aux_reg_writel, dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
acpi_timer_count(void *priv)
|
acpi_timer_count(void *priv)
|
||||||
{
|
{
|
||||||
@@ -711,21 +946,28 @@ acpi_set_timer32(acpi_t *dev, uint8_t timer32)
|
|||||||
void
|
void
|
||||||
acpi_set_slot(acpi_t *dev, int slot)
|
acpi_set_slot(acpi_t *dev, int slot)
|
||||||
{
|
{
|
||||||
dev->regs.slot = slot;
|
dev->slot = slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
acpi_set_irq_mode(acpi_t *dev, int irq_mode)
|
acpi_set_irq_mode(acpi_t *dev, int irq_mode)
|
||||||
{
|
{
|
||||||
dev->regs.irq_mode = irq_mode;
|
dev->irq_mode = irq_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
acpi_set_irq_pin(acpi_t *dev, int irq_pin)
|
acpi_set_irq_pin(acpi_t *dev, int irq_pin)
|
||||||
{
|
{
|
||||||
dev->regs.irq_pin = irq_pin;
|
dev->irq_pin = irq_pin;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
acpi_set_irq_line(acpi_t *dev, int irq_line)
|
||||||
|
{
|
||||||
|
dev->irq_line = irq_line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -821,6 +1063,8 @@ acpi_init(const device_t *info)
|
|||||||
|
|
||||||
dev->vendor = info->local;
|
dev->vendor = info->local;
|
||||||
|
|
||||||
|
dev->irq_line = 9;
|
||||||
|
|
||||||
if (dev->vendor == VEN_INTEL) {
|
if (dev->vendor == VEN_INTEL) {
|
||||||
dev->apm = device_add(&apm_pci_acpi_device);
|
dev->apm = device_add(&apm_pci_acpi_device);
|
||||||
io_sethandler(0x00b2, 0x0002, acpi_apm_in, NULL, NULL, acpi_apm_out, NULL, NULL, dev);
|
io_sethandler(0x00b2, 0x0002, acpi_apm_in, NULL, NULL, acpi_apm_out, NULL, NULL, dev);
|
||||||
@@ -837,7 +1081,7 @@ acpi_init(const device_t *info)
|
|||||||
|
|
||||||
const device_t acpi_intel_device =
|
const device_t acpi_intel_device =
|
||||||
{
|
{
|
||||||
"ACPI v1.0",
|
"Intel ACPI",
|
||||||
DEVICE_PCI,
|
DEVICE_PCI,
|
||||||
VEN_INTEL,
|
VEN_INTEL,
|
||||||
acpi_init,
|
acpi_init,
|
||||||
@@ -852,7 +1096,7 @@ const device_t acpi_intel_device =
|
|||||||
|
|
||||||
const device_t acpi_via_device =
|
const device_t acpi_via_device =
|
||||||
{
|
{
|
||||||
"ACPI v1.2",
|
"VIA ACPI",
|
||||||
DEVICE_PCI,
|
DEVICE_PCI,
|
||||||
VEN_VIA,
|
VEN_VIA,
|
||||||
acpi_init,
|
acpi_init,
|
||||||
@@ -863,3 +1107,18 @@ const device_t acpi_via_device =
|
|||||||
NULL,
|
NULL,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const device_t acpi_smc_device =
|
||||||
|
{
|
||||||
|
"SMC FDC73C931APM ACPI",
|
||||||
|
DEVICE_PCI,
|
||||||
|
VEN_SMC,
|
||||||
|
acpi_init,
|
||||||
|
acpi_close,
|
||||||
|
acpi_reset,
|
||||||
|
NULL,
|
||||||
|
acpi_speed_changed,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
@@ -27,6 +27,9 @@ extern "C" {
|
|||||||
|
|
||||||
#define RSM_STS (1 << 15)
|
#define RSM_STS (1 << 15)
|
||||||
#define PWRBTN_STS (1 << 8)
|
#define PWRBTN_STS (1 << 8)
|
||||||
|
#define GBL_STS (1 << 5)
|
||||||
|
#define BM_STS (1 << 4)
|
||||||
|
#define TMROF_STS (1 << 0)
|
||||||
|
|
||||||
#define RTC_EN (1 << 10)
|
#define RTC_EN (1 << 10)
|
||||||
#define PWRBTN_EN (1 << 8)
|
#define PWRBTN_EN (1 << 8)
|
||||||
@@ -40,6 +43,7 @@ extern "C" {
|
|||||||
#define ACPI_DISABLE 0xf0
|
#define ACPI_DISABLE 0xf0
|
||||||
|
|
||||||
#define VEN_INTEL 0x8086
|
#define VEN_INTEL 0x8086
|
||||||
|
#define VEN_SMC 0x1055
|
||||||
#define VEN_VIA 0x1106
|
#define VEN_VIA 0x1106
|
||||||
|
|
||||||
|
|
||||||
@@ -52,13 +56,11 @@ typedef struct
|
|||||||
gpireg[3], gporeg[4];
|
gpireg[3], gporeg[4];
|
||||||
uint16_t pmsts, pmen,
|
uint16_t pmsts, pmen,
|
||||||
pmcntrl, gpsts,
|
pmcntrl, gpsts,
|
||||||
gpen, io_base,
|
gpen, gpscien,
|
||||||
gpscien, gpsmien,
|
gpsmien, pscntrl,
|
||||||
pscntrl, gpo_val,
|
gpo_val, gpi_val,
|
||||||
gpi_val;
|
gpscists;
|
||||||
int slot, irq_mode,
|
int smi_lock, smi_active;
|
||||||
irq_pin, smi_lock,
|
|
||||||
smi_active;
|
|
||||||
uint32_t pcntrl, glbsts,
|
uint32_t pcntrl, glbsts,
|
||||||
devsts, glben,
|
devsts, glben,
|
||||||
glbctl, devctl,
|
glbctl, devctl,
|
||||||
@@ -72,7 +74,10 @@ typedef struct
|
|||||||
{
|
{
|
||||||
acpi_regs_t regs;
|
acpi_regs_t regs;
|
||||||
uint8_t gporeg_default[4];
|
uint8_t gporeg_default[4];
|
||||||
int vendor;
|
uint16_t io_base, aux_io_base;
|
||||||
|
int vendor,
|
||||||
|
slot, irq_mode,
|
||||||
|
irq_pin, irq_line;
|
||||||
pc_timer_t timer;
|
pc_timer_t timer;
|
||||||
nvr_t *nvr;
|
nvr_t *nvr;
|
||||||
apm_t *apm;
|
apm_t *apm;
|
||||||
@@ -81,16 +86,19 @@ typedef struct
|
|||||||
|
|
||||||
/* Global variables. */
|
/* Global variables. */
|
||||||
extern const device_t acpi_intel_device;
|
extern const device_t acpi_intel_device;
|
||||||
|
extern const device_t acpi_smc_device;
|
||||||
extern const device_t acpi_via_device;
|
extern const device_t acpi_via_device;
|
||||||
|
|
||||||
|
|
||||||
/* Functions. */
|
/* Functions. */
|
||||||
extern void acpi_update_io_mapping(acpi_t *dev, uint32_t base, int chipset_en);
|
extern void acpi_update_io_mapping(acpi_t *dev, uint32_t base, int chipset_en);
|
||||||
|
extern void acpi_update_aux_io_mapping(acpi_t *dev, uint32_t base, int chipset_en);
|
||||||
extern void acpi_init_gporeg(acpi_t *dev, uint8_t val0, uint8_t val1, uint8_t val2, uint8_t val3);
|
extern void acpi_init_gporeg(acpi_t *dev, uint8_t val0, uint8_t val1, uint8_t val2, uint8_t val3);
|
||||||
extern void acpi_set_timer32(acpi_t *dev, uint8_t timer32);
|
extern void acpi_set_timer32(acpi_t *dev, uint8_t timer32);
|
||||||
extern void acpi_set_slot(acpi_t *dev, int slot);
|
extern void acpi_set_slot(acpi_t *dev, int slot);
|
||||||
extern void acpi_set_irq_mode(acpi_t *dev, int irq_mode);
|
extern void acpi_set_irq_mode(acpi_t *dev, int irq_mode);
|
||||||
extern void acpi_set_irq_pin(acpi_t *dev, int irq_pin);
|
extern void acpi_set_irq_pin(acpi_t *dev, int irq_pin);
|
||||||
|
extern void acpi_set_irq_line(acpi_t *dev, int irq_line);
|
||||||
extern void acpi_set_nvr(acpi_t *dev, nvr_t *nvr);
|
extern void acpi_set_nvr(acpi_t *dev, nvr_t *nvr);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@@ -22,6 +22,7 @@ extern const device_t fdc37c663_device;
|
|||||||
extern const device_t fdc37c665_device;
|
extern const device_t fdc37c665_device;
|
||||||
extern const device_t fdc37c666_device;
|
extern const device_t fdc37c666_device;
|
||||||
extern const device_t fdc37c669_device;
|
extern const device_t fdc37c669_device;
|
||||||
|
extern const device_t fdc37c931apm_device;
|
||||||
extern const device_t fdc37c932fr_device;
|
extern const device_t fdc37c932fr_device;
|
||||||
extern const device_t fdc37c932qf_device;
|
extern const device_t fdc37c932qf_device;
|
||||||
extern const device_t fdc37c935_device;
|
extern const device_t fdc37c935_device;
|
||||||
|
@@ -31,6 +31,8 @@
|
|||||||
#include <86box/fdd.h>
|
#include <86box/fdd.h>
|
||||||
#include <86box/fdc.h>
|
#include <86box/fdc.h>
|
||||||
#include <86box/nvr.h>
|
#include <86box/nvr.h>
|
||||||
|
#include <86box/apm.h>
|
||||||
|
#include <86box/acpi.h>
|
||||||
#include <86box/sio.h>
|
#include <86box/sio.h>
|
||||||
|
|
||||||
|
|
||||||
@@ -47,10 +49,11 @@ typedef struct {
|
|||||||
} access_bus_t;
|
} access_bus_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t chip_id, tries,
|
uint8_t chip_id, is_apm,
|
||||||
|
tries,
|
||||||
gpio_regs[2], auxio_reg,
|
gpio_regs[2], auxio_reg,
|
||||||
regs[48],
|
regs[48],
|
||||||
ld_regs[10][256];
|
ld_regs[11][256];
|
||||||
uint16_t gpio_base, /* Set to EA */
|
uint16_t gpio_base, /* Set to EA */
|
||||||
auxio_base, nvr_sec_base;
|
auxio_base, nvr_sec_base;
|
||||||
int locked,
|
int locked,
|
||||||
@@ -59,6 +62,7 @@ typedef struct {
|
|||||||
serial_t *uart[2];
|
serial_t *uart[2];
|
||||||
access_bus_t *access_bus;
|
access_bus_t *access_bus;
|
||||||
nvr_t *nvr;
|
nvr_t *nvr;
|
||||||
|
acpi_t *acpi;
|
||||||
} fdc37c93x_t;
|
} fdc37c93x_t;
|
||||||
|
|
||||||
|
|
||||||
@@ -223,7 +227,8 @@ fdc37c93x_auxio_handler(fdc37c93x_t *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void fdc37c93x_gpio_handler(fdc37c93x_t *dev)
|
static void
|
||||||
|
fdc37c93x_gpio_handler(fdc37c93x_t *dev)
|
||||||
{
|
{
|
||||||
uint16_t ld_port = 0;
|
uint16_t ld_port = 0;
|
||||||
uint8_t local_enable;
|
uint8_t local_enable;
|
||||||
@@ -256,7 +261,7 @@ static void fdc37c93x_gpio_handler(fdc37c93x_t *dev)
|
|||||||
|
|
||||||
|
|
||||||
static uint8_t
|
static uint8_t
|
||||||
fdc37c932fr_access_bus_read(uint16_t port, void *priv)
|
fdc37c93x_access_bus_read(uint16_t port, void *priv)
|
||||||
{
|
{
|
||||||
access_bus_t *dev = (access_bus_t *) priv;
|
access_bus_t *dev = (access_bus_t *) priv;
|
||||||
uint8_t ret = 0xff;
|
uint8_t ret = 0xff;
|
||||||
@@ -281,7 +286,7 @@ fdc37c932fr_access_bus_read(uint16_t port, void *priv)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fdc37c932fr_access_bus_write(uint16_t port, uint8_t val, void *priv)
|
fdc37c93x_access_bus_write(uint16_t port, uint8_t val, void *priv)
|
||||||
{
|
{
|
||||||
access_bus_t *dev = (access_bus_t *) priv;
|
access_bus_t *dev = (access_bus_t *) priv;
|
||||||
|
|
||||||
@@ -303,23 +308,49 @@ fdc37c932fr_access_bus_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void fdc37c932fr_access_bus_handler(fdc37c93x_t *dev)
|
static void
|
||||||
|
fdc37c93x_access_bus_handler(fdc37c93x_t *dev)
|
||||||
{
|
{
|
||||||
uint16_t ld_port = 0;
|
uint16_t ld_port = 0;
|
||||||
uint8_t global_enable = !!(dev->regs[0x22] & (1 << 6));
|
uint8_t global_enable = !!(dev->regs[0x22] & (1 << 6));
|
||||||
uint8_t local_enable = !!dev->ld_regs[9][0x30];
|
uint8_t local_enable = !!dev->ld_regs[9][0x30];
|
||||||
|
|
||||||
io_removehandler(dev->access_bus->base, 0x0004,
|
io_removehandler(dev->access_bus->base, 0x0004,
|
||||||
fdc37c932fr_access_bus_read, NULL, NULL, fdc37c932fr_access_bus_write, NULL, NULL, dev->access_bus);
|
fdc37c93x_access_bus_read, NULL, NULL, fdc37c93x_access_bus_write, NULL, NULL, dev->access_bus);
|
||||||
if (global_enable && local_enable) {
|
if (global_enable && local_enable) {
|
||||||
dev->access_bus->base = ld_port = make_port(dev, 9);
|
dev->access_bus->base = ld_port = make_port(dev, 9);
|
||||||
if ((ld_port >= 0x0100) && (ld_port <= 0x0FFC))
|
if ((ld_port >= 0x0100) && (ld_port <= 0x0FFC))
|
||||||
io_sethandler(dev->access_bus->base, 0x0004,
|
io_sethandler(dev->access_bus->base, 0x0004,
|
||||||
fdc37c932fr_access_bus_read, NULL, NULL, fdc37c932fr_access_bus_write, NULL, NULL, dev->access_bus);
|
fdc37c93x_access_bus_read, NULL, NULL, fdc37c93x_access_bus_write, NULL, NULL, dev->access_bus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
fdc37c93x_acpi_handler(fdc37c93x_t *dev)
|
||||||
|
{
|
||||||
|
uint16_t ld_port = 0;
|
||||||
|
uint8_t local_enable = !!dev->ld_regs[0x0a][0x30];
|
||||||
|
uint8_t sci_irq = dev->ld_regs[0x0a][0x70];
|
||||||
|
|
||||||
|
acpi_update_io_mapping(dev->acpi, 0x0000, local_enable);
|
||||||
|
if (local_enable) {
|
||||||
|
ld_port = make_port(dev, 0x0a);
|
||||||
|
if ((ld_port >= 0x0100) && (ld_port <= 0x0FF0))
|
||||||
|
acpi_update_io_mapping(dev->acpi, ld_port, local_enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
acpi_update_aux_io_mapping(dev->acpi, 0x0000, local_enable);
|
||||||
|
if (local_enable) {
|
||||||
|
ld_port = make_port_sec(dev, 0x0a);
|
||||||
|
if ((ld_port >= 0x0100) && (ld_port <= 0x0FF8))
|
||||||
|
acpi_update_aux_io_mapping(dev->acpi, ld_port, local_enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
acpi_set_irq_line(dev->acpi, sci_irq);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fdc37c93x_write(uint16_t port, uint8_t val, void *priv)
|
fdc37c93x_write(uint16_t port, uint8_t val, void *priv)
|
||||||
{
|
{
|
||||||
@@ -361,17 +392,23 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
if (((dev->cur_reg & 0xF0) == 0x70) && (dev->regs[7] < 4))
|
if (((dev->cur_reg & 0xF0) == 0x70) && (dev->regs[7] < 4))
|
||||||
return;
|
return;
|
||||||
/* Block writes to some logical devices. */
|
/* Block writes to some logical devices. */
|
||||||
if (dev->regs[7] > 9)
|
if (dev->regs[7] > 0x0a)
|
||||||
return;
|
return;
|
||||||
else switch (dev->regs[7]) {
|
else switch (dev->regs[7]) {
|
||||||
case 1:
|
case 0x01:
|
||||||
case 2:
|
case 0x02:
|
||||||
case 7:
|
case 0x07:
|
||||||
return;
|
return;
|
||||||
case 9:
|
case 0x09:
|
||||||
/* If we're on the FDC37C935, return as this is not a valid
|
/* If we're on the FDC37C935, return as this is not a valid
|
||||||
logical device there. */
|
logical device there. */
|
||||||
if (dev->chip_id == 0x02)
|
if (!dev->is_apm && (dev->chip_id == 0x02))
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
case 0x0a:
|
||||||
|
/* If we're not on the FDC37C931APM, return as this is not a
|
||||||
|
valid logical device there. */
|
||||||
|
if (!dev->is_apm)
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -398,7 +435,7 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
if (valxor & 0x20)
|
if (valxor & 0x20)
|
||||||
fdc37c93x_serial_handler(dev, 1);
|
fdc37c93x_serial_handler(dev, 1);
|
||||||
if ((valxor & 0x40) && (dev->chip_id != 0x02))
|
if ((valxor & 0x40) && (dev->chip_id != 0x02))
|
||||||
fdc37c932fr_access_bus_handler(dev);
|
fdc37c93x_access_bus_handler(dev);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -564,7 +601,7 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
/* Access bus (FDC37C932FR only) */
|
/* Access bus (FDC37C932FR and FDC37C931APM only) */
|
||||||
switch(dev->cur_reg) {
|
switch(dev->cur_reg) {
|
||||||
case 0x30:
|
case 0x30:
|
||||||
case 0x60:
|
case 0x60:
|
||||||
@@ -573,7 +610,21 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
if ((dev->cur_reg == 0x30) && (val & 0x01))
|
if ((dev->cur_reg == 0x30) && (val & 0x01))
|
||||||
dev->regs[0x22] |= 0x40;
|
dev->regs[0x22] |= 0x40;
|
||||||
if (valxor)
|
if (valxor)
|
||||||
fdc37c932fr_access_bus_handler(dev);
|
fdc37c93x_access_bus_handler(dev);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
/* Access bus (FDC37C931APM only) */
|
||||||
|
switch(dev->cur_reg) {
|
||||||
|
case 0x30:
|
||||||
|
case 0x60:
|
||||||
|
case 0x61:
|
||||||
|
case 0x62:
|
||||||
|
case 0x63:
|
||||||
|
case 0x70:
|
||||||
|
if (valxor)
|
||||||
|
fdc37c93x_acpi_handler(dev);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -694,13 +745,17 @@ fdc37c93x_reset(fdc37c93x_t *dev)
|
|||||||
|
|
||||||
/* Logical device 9: ACCESS.bus */
|
/* Logical device 9: ACCESS.bus */
|
||||||
|
|
||||||
|
/* Logical device A: ACPI */
|
||||||
|
|
||||||
fdc37c93x_gpio_handler(dev);
|
fdc37c93x_gpio_handler(dev);
|
||||||
fdc37c93x_lpt_handler(dev);
|
fdc37c93x_lpt_handler(dev);
|
||||||
fdc37c93x_serial_handler(dev, 0);
|
fdc37c93x_serial_handler(dev, 0);
|
||||||
fdc37c93x_serial_handler(dev, 1);
|
fdc37c93x_serial_handler(dev, 1);
|
||||||
fdc37c93x_auxio_handler(dev);
|
fdc37c93x_auxio_handler(dev);
|
||||||
if (dev->chip_id == 0x03)
|
if (dev->is_apm || (dev->chip_id == 0x03))
|
||||||
fdc37c932fr_access_bus_handler(dev);
|
fdc37c93x_access_bus_handler(dev);
|
||||||
|
if (dev->is_apm)
|
||||||
|
fdc37c93x_acpi_handler(dev);
|
||||||
|
|
||||||
fdc_reset(dev->fdc);
|
fdc_reset(dev->fdc);
|
||||||
fdc37c93x_fdc_handler(dev);
|
fdc37c93x_fdc_handler(dev);
|
||||||
@@ -758,7 +813,8 @@ fdc37c93x_init(const device_t *info)
|
|||||||
dev->uart[0] = device_add_inst(&ns16550_device, 1);
|
dev->uart[0] = device_add_inst(&ns16550_device, 1);
|
||||||
dev->uart[1] = device_add_inst(&ns16550_device, 2);
|
dev->uart[1] = device_add_inst(&ns16550_device, 2);
|
||||||
|
|
||||||
dev->chip_id = info->local;
|
dev->chip_id = info->local & 0xff;
|
||||||
|
dev->is_apm = info->local >> 8;
|
||||||
|
|
||||||
dev->gpio_regs[0] = 0xff;
|
dev->gpio_regs[0] = 0xff;
|
||||||
dev->gpio_regs[1] = 0xfd;
|
dev->gpio_regs[1] = 0xfd;
|
||||||
@@ -773,6 +829,9 @@ fdc37c93x_init(const device_t *info)
|
|||||||
if (dev->chip_id == 0x03)
|
if (dev->chip_id == 0x03)
|
||||||
dev->access_bus = device_add(&access_bus_device);
|
dev->access_bus = device_add(&access_bus_device);
|
||||||
|
|
||||||
|
if (dev->is_apm)
|
||||||
|
dev->acpi = device_add(&acpi_smc_device);
|
||||||
|
|
||||||
io_sethandler(0x370, 0x0002,
|
io_sethandler(0x370, 0x0002,
|
||||||
fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, dev);
|
fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, dev);
|
||||||
io_sethandler(0x3f0, 0x0002,
|
io_sethandler(0x3f0, 0x0002,
|
||||||
@@ -784,6 +843,15 @@ fdc37c93x_init(const device_t *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const device_t fdc37c931apm_device = {
|
||||||
|
"SMC FDC37C932QF Super I/O",
|
||||||
|
0,
|
||||||
|
0x130, /* Share the same ID with the 932QF. */
|
||||||
|
fdc37c93x_init, fdc37c93x_close, NULL,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
const device_t fdc37c932fr_device = {
|
const device_t fdc37c932fr_device = {
|
||||||
"SMC FDC37C932FR Super I/O",
|
"SMC FDC37C932FR Super I/O",
|
||||||
0,
|
0,
|
||||||
@@ -796,7 +864,7 @@ const device_t fdc37c932fr_device = {
|
|||||||
const device_t fdc37c932qf_device = {
|
const device_t fdc37c932qf_device = {
|
||||||
"SMC FDC37C932QF Super I/O",
|
"SMC FDC37C932QF Super I/O",
|
||||||
0,
|
0,
|
||||||
0x30, /* Share the same ID with the 935. */
|
0x30,
|
||||||
fdc37c93x_init, fdc37c93x_close, NULL,
|
fdc37c93x_init, fdc37c93x_close, NULL,
|
||||||
NULL, NULL, NULL,
|
NULL, NULL, NULL,
|
||||||
NULL
|
NULL
|
||||||
|
Reference in New Issue
Block a user