/* * PIIX4 ACPI controller emulation * * Winston liwen Wang, winston.l.wang@intel.com * Copyright (c) 2006 , Intel Corporation. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include "vl.h" #define FREQUENCE_PMTIMER 3579545 /* acpi register bit define here */ /* PM1_STS */ #define TMROF_STS (1 << 0) #define BM_STS (1 << 4) #define GBL_STS (1 << 5) #define PWRBTN_STS (1 << 8) #define RTC_STS (1 << 10) #define PRBTNOR_STS (1 << 11) #define WAK_STS (1 << 15) /* PM1_EN */ #define TMROF_EN (1 << 0) #define GBL_EN (1 << 5) #define PWRBTN_EN (1 << 8) #define RTC_EN (1 << 10) /* PM1_CNT */ #define SCI_EN (1 << 0) #define GBL_RLS (1 << 2) #define SLP_EN (1 << 13) /* Bits of PM1a register define here */ #define SLP_TYP_MASK 0x1C00 #define SLP_VAL 0x1C00 typedef struct AcpiDeviceState AcpiDeviceState; AcpiDeviceState *acpi_device_table; typedef struct PM1Event_BLK { uint16_t pm1_status; /* pm1a_EVT_BLK */ uint16_t pm1_enable; /* pm1a_EVT_BLK+2 */ }PM1Event_BLK; typedef struct PCIAcpiState { PCIDevice dev; uint16_t irq; uint16_t pm1_status; /* pm1a_EVT_BLK */ uint16_t pm1_enable; /* pm1a_EVT_BLK+2 */ uint16_t pm1_control; /* pm1a_ECNT_BLK */ uint32_t pm1_timer; /* pmtmr_BLK */ uint64_t old_vmck_ticks; /* using vm_clock counter */ } PCIAcpiState; static PCIAcpiState *acpi_state; static void acpi_reset(PCIAcpiState *s) { uint8_t *pci_conf; pci_conf = s->dev.config; pci_conf[0x42] = 0x00; pci_conf[0x43] = 0x00; s->irq = 9; s->pm1_status = 0; s->pm1_enable = 0x00; /* TMROF_EN should cleared */ s->pm1_control = SCI_EN; /* SCI_EN */ s->pm1_timer = 0; s->old_vmck_ticks = qemu_get_clock(vm_clock); } /*byte access */ static void acpiPm1Status_writeb(void *opaque, uint32_t addr, uint32_t val) { PCIAcpiState *s = opaque; if ((val&TMROF_STS)==TMROF_STS) s->pm1_status = s->pm1_status&!TMROF_STS; if ((val&GBL_STS)==GBL_STS) s->pm1_status = s->pm1_status&!GBL_STS; /* printf("acpiPm1Status_writeb \n addr %x val:%x pm1_status:%x \n", addr, val,s->pm1_status); */ } static uint32_t acpiPm1Status_readb(void *opaque, uint32_t addr) { PCIAcpiState *s = opaque; uint32_t val; val = s->pm1_status; /* printf("acpiPm1Status_readb \n addr %x val:%x\n", addr, val); */ return val; } static void acpiPm1StatusP1_writeb(void *opaque, uint32_t addr, uint32_t val) { PCIAcpiState *s = opaque; s->pm1_status = (val<<8)||(s->pm1_status); /* printf("acpiPm1StatusP1_writeb \n addr %x val:%x\n", addr, val); */ } static uint32_t acpiPm1Status