X-Git-Url: https://vcs.maemo.org/git/?a=blobdiff_plain;f=hw%2Facpi.c;h=6e3f69eac569b555b156fe85017dfe65fdb10260;hb=cd346349b45ef056f138a184f660b8c34c3213cc;hp=ce3f7f2df60a33923c5971b0c0e88d1df05a27dd;hpb=7b717336e2873fd6d9f178a12549eaa2367d14d0;p=qemu diff --git a/hw/acpi.c b/hw/acpi.c index ce3f7f2..6e3f69e 100644 --- a/hw/acpi.c +++ b/hw/acpi.c @@ -1,8 +1,8 @@ /* * ACPI implementation - * + * * Copyright (c) 2006 Fabrice Bellard - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2 as published by the Free Software Foundation. @@ -54,6 +54,9 @@ typedef struct PIIX4PMState { #define SUS_EN (1 << 13) +#define ACPI_ENABLE 0xf1 +#define ACPI_DISABLE 0xf0 + #define SMBHSTSTS 0x00 #define SMBHSTCNT 0x02 #define SMBHSTCMD 0x03 @@ -84,9 +87,9 @@ static void pm_update_sci(PIIX4PMState *s) { int sci_level, pmsts; int64_t expire_time; - + pmsts = get_pmsts(s); - sci_level = (((pmsts & s->pmen) & + sci_level = (((pmsts & s->pmen) & (RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN)) != 0); qemu_set_irq(s->dev.irq[0], sci_level); /* schedule a timer interruption if needed */ @@ -216,6 +219,14 @@ static void pm_smi_writeb(void *opaque, uint32_t addr, uint32_t val) #endif if (addr == 0) { s->apmc = val; + + /* ACPI specs 3.0, 4.7.2.5 */ + if (val == ACPI_ENABLE) { + s->pmcntrl |= SCI_EN; + } else if (val == ACPI_DISABLE) { + s->pmcntrl &= ~SCI_EN; + } + if (s->dev.config[0x5b] & (1 << 1)) { cpu_interrupt(first_cpu, CPU_INTERRUPT_SMI); } @@ -228,7 +239,7 @@ static uint32_t pm_smi_readb(void *opaque, uint32_t addr) { PIIX4PMState *s = opaque; uint32_t val; - + addr &= 1; if (addr == 0) { val = s->apmc; @@ -389,7 +400,7 @@ static void pm_io_space_update(PIIX4PMState *s) if (s->dev.config[0x80] & 1) { pm_io_base = le32_to_cpu(*(uint32_t *)(s->dev.config + 0x40)); - pm_io_base &= 0xfffe; + pm_io_base &= 0xffc0; /* XXX: need to improve memory and ioport allocation */ #if defined(DEBUG) @@ -402,7 +413,7 @@ static void pm_io_space_update(PIIX4PMState *s) } } -static void pm_write_config(PCIDevice *d, +static void pm_write_config(PCIDevice *d, uint32_t address, uint32_t val, int len) { pci_default_write_config(d, address, val, len); @@ -463,15 +474,17 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base) pci_conf[0x01] = 0x80; pci_conf[0x02] = 0x13; pci_conf[0x03] = 0x71; + pci_conf[0x06] = 0x80; + pci_conf[0x07] = 0x02; pci_conf[0x08] = 0x00; // revision number pci_conf[0x09] = 0x00; pci_conf[0x0a] = 0x80; // other bridge device pci_conf[0x0b] = 0x06; // bridge device pci_conf[0x0e] = 0x00; // header_type pci_conf[0x3d] = 0x01; // interrupt pin 1 - + pci_conf[0x40] = 0x01; /* PM io base read only bit */ - + register_ioport_write(0xb2, 2, 1, pm_smi_writeb, s); register_ioport_read(0xb2, 2, 1, pm_smi_readb, s);