debuggers.hg
changeset 10981:1de1bb6a51c5
[qemu] Update acpi timer to not use a qemu timer.
Compute the acpi timer's value when it is accessed instead of using
a qemu timer to keep it uptodate.
From: Wang, Winston L <winston.l.wang@intel.com>
Signed-off-by: Christian Limpach <Christian.Limpach@xensource.com>
Compute the acpi timer's value when it is accessed instead of using
a qemu timer to keep it uptodate.
From: Wang, Winston L <winston.l.wang@intel.com>
Signed-off-by: Christian Limpach <Christian.Limpach@xensource.com>
author | chris@kneesaa.uk.xensource.com |
---|---|
date | Fri Aug 04 11:33:41 2006 +0100 (2006-08-04) |
parents | c908f4c9150d |
children | 23166260f6ce |
files | tools/ioemu/hw/piix4acpi.c |
line diff
1.1 --- a/tools/ioemu/hw/piix4acpi.c Fri Aug 04 11:03:17 2006 +0100 1.2 +++ b/tools/ioemu/hw/piix4acpi.c Fri Aug 04 11:33:41 2006 +0100 1.3 @@ -24,26 +24,26 @@ 1.4 */ 1.5 1.6 #include "vl.h" 1.7 -#define FREQUENCE_PMTIMER 3753425 1.8 +#define FREQUENCE_PMTIMER 3579545 1.9 /* acpi register bit define here */ 1.10 1.11 -/* PM1_STS */ 1.12 -#define TMROF_STS (1 << 0) 1.13 -#define BM_STS (1 << 4) 1.14 -#define GBL_STS (1 << 5) 1.15 -#define PWRBTN_STS (1 << 8) 1.16 -#define RTC_STS (1 << 10) 1.17 +/* PM1_STS */ 1.18 +#define TMROF_STS (1 << 0) 1.19 +#define BM_STS (1 << 4) 1.20 +#define GBL_STS (1 << 5) 1.21 +#define PWRBTN_STS (1 << 8) 1.22 +#define RTC_STS (1 << 10) 1.23 #define PRBTNOR_STS (1 << 11) 1.24 -#define WAK_STS (1 << 15) 1.25 -/* PM1_EN */ 1.26 +#define WAK_STS (1 << 15) 1.27 +/* PM1_EN */ 1.28 #define TMROF_EN (1 << 0) 1.29 #define GBL_EN (1 << 5) 1.30 #define PWRBTN_EN (1 << 8) 1.31 -#define RTC_EN (1 << 10) 1.32 -/* PM1_CNT */ 1.33 +#define RTC_EN (1 << 10) 1.34 +/* PM1_CNT */ 1.35 #define SCI_EN (1 << 0) 1.36 #define GBL_RLS (1 << 2) 1.37 -#define SLP_EN (1 << 13) 1.38 +#define SLP_EN (1 << 13) 1.39 1.40 /* Bits of PM1a register define here */ 1.41 #define SLP_TYP_MASK 0x1C00 1.42 @@ -52,14 +52,6 @@ 1.43 typedef struct AcpiDeviceState AcpiDeviceState; 1.44 AcpiDeviceState *acpi_device_table; 1.45 1.46 -/* Bits of PM1a register define here */ 1.47 -typedef struct PMTState { 1.48 - uint32_t count; 1.49 - int irq; 1.50 - uint64_t next_pm_time; 1.51 - QEMUTimer *pm_timer; 1.52 -}PMTState; 1.53 - 1.54 typedef struct PM1Event_BLK { 1.55 uint16_t pm1_status; /* pm1a_EVT_BLK */ 1.56 uint16_t pm1_enable; /* pm1a_EVT_BLK+2 */ 1.57 @@ -72,84 +64,11 @@ typedef struct PCIAcpiState { 1.58 uint16_t pm1_enable; /* pm1a_EVT_BLK+2 */ 1.59 uint16_t pm1_control; /* pm1a_ECNT_BLK */ 1.60 uint32_t pm1_timer; /* pmtmr_BLK */ 1.61 + uint64_t old_vmck_ticks /* using vm_clock counter */ 1.62 } PCIAcpiState; 1.63 1.64 -static PMTState *pmtimer_state; 1.65 static PCIAcpiState *acpi_state; 1.66 1.67 -static void pmtimer_save(QEMUFile *f, void *opaque) 1.68 -{ 1.69 - PMTState *s = opaque; 1.70 - 1.71 - qemu_put_be32s(f, &s->count); 1.72 - qemu_put_be32s(f, &s->irq); 1.73 - qemu_put_be64s(f, &s->next_pm_time); 1.74 - qemu_put_timer(f, s->pm_timer); 1.75 -} 1.76 - 1.77 -static int pmtimer_load(QEMUFile *f, void *opaque, int version_id) 1.78 -{ 1.79 - PMTState *s = opaque; 1.80 - 1.81 - if (version_id != 1) 1.82 - return -EINVAL; 1.83 - qemu_get_be32s(f, &s->count); 1.84 - qemu_get_be32s(f, &s->irq); 1.85 - qemu_get_be64s(f, &s->next_pm_time); 1.86 - qemu_get_timer(f, s->pm_timer); 1.87 - return 0; 1.88 -} 1.89 - 1.90 -static inline void acpi_set_irq(PCIAcpiState *s) 1.91 -{ 1.92 -/* no real SCI event need for now, so comment the following line out */ 1.93 -/* pic_set_irq(s->irq, 1); */ 1.94 - printf("acpi_set_irq: s->irq %x \n",s->irq); 1.95 -} 1.96 - 1.97 -static void pm_timer_update(void *opaque) 1.98 -{ 1.99 - PMTState *s = opaque; 1.100 - s->next_pm_time = qemu_get_clock(vm_clock) + 1.101 - muldiv64(1, ticks_per_sec,FREQUENCE_PMTIMER); 1.102 - qemu_mod_timer(s->pm_timer, s->next_pm_time); 1.103 - acpi_state->pm1_timer ++; 1.104 - 1.105 - /* If pm timer is zero then reset it to zero. */ 1.106 - if (acpi_state->pm1_timer >= 0x1000000) { 1.107 -/* printf("pm_timerupdate: timer overflow: %x \n", acpi_state->pm1_timer); */ 1.108 - 1.109 - acpi_state->pm1_timer = 0; 1.110 - acpi_state->pm1_status = acpi_state->pm1_status | TMROF_STS; 1.111 - /* If TMROF_EN is set then send the irq. */ 1.112 - if ((acpi_state->pm1_enable & TMROF_EN) == TMROF_EN) { 1.113 - acpi_set_irq(acpi_state); 1.114 - acpi_state->pm1_enable = 0x00; /* only need one time...*/ 1.115 - } 1.116 - } 1.117 - s->count = acpi_state->pm1_timer; 1.118 -} 1.119 - 1.120 -static PMTState *pmtimer_init(void) 1.121 -{ 1.122 - PMTState *s; 1.123 - 1.124 - s = qemu_mallocz(sizeof(PMTState)); 1.125 - if (!s) 1.126 - return NULL; 1.127 - 1.128 - /* s->irq = irq; */ 1.129 - 1.130 - s->pm_timer = qemu_new_timer(vm_clock, pm_timer_update, s); 1.131 - 1.132 - s->count = 0; 1.133 - s->next_pm_time = qemu_get_clock(vm_clock) + muldiv64(1, ticks_per_sec,FREQUENCE_PMTIMER) + 1; 1.134 - qemu_mod_timer(s->pm_timer, s->next_pm_time); 1.135 - 1.136 - register_savevm("pm timer", 1, 1, pmtimer_save, pmtimer_load, s); 1.137 - return s; 1.138 -} 1.139 - 1.140 static void acpi_reset(PCIAcpiState *s) 1.141 { 1.142 uint8_t *pci_conf; 1.143 @@ -162,6 +81,7 @@ static void acpi_reset(PCIAcpiState *s) 1.144 s->pm1_enable = 0x00; /* TMROF_EN should cleared */ 1.145 s->pm1_control = SCI_EN; /* SCI_EN */ 1.146 s->pm1_timer = 0; 1.147 + s->old_vmck_ticks = qemu_get_clock(vm_clock); 1.148 } 1.149 1.150 /*byte access */ 1.151 @@ -173,8 +93,8 @@ static void acpiPm1Status_writeb(void *o 1.152 s->pm1_status = s->pm1_status&!TMROF_STS; 1.153 1.154 if ((val&GBL_STS)==GBL_STS) 1.155 - s->pm1_status = s->pm1_status&!GBL_STS; 1.156 - 1.157 + s->pm1_status = s->pm1_status&!GBL_STS; 1.158 + 1.159 /* printf("acpiPm1Status_writeb \n addr %x val:%x pm1_status:%x \n", addr, val,s->pm1_status); */ 1.160 } 1.161 1.162 @@ -193,7 +113,7 @@ static void acpiPm1StatusP1_writeb(void 1.163 { 1.164 PCIAcpiState *s = opaque; 1.165 1.166 - s->pm1_status = (val<<8)||(s->pm1_status); 1.167 + s->pm1_status = (val<<8)||(s->pm1_status); 1.168 /* printf("acpiPm1StatusP1_writeb \n addr %x val:%x\n", addr, val); */ 1.169 } 1.170 1.171 @@ -305,7 +225,7 @@ static void acpiPm1Status_writew(void *o 1.172 s->pm1_status = s->pm1_status&!TMROF_STS; 1.173 1.174 if ((val&GBL_STS)==GBL_STS) 1.175 - s->pm1_status = s->pm1_status&!GBL_STS; 1.176 + s->pm1_status = s->pm1_status&!GBL_STS; 1.177 1.178 /* printf("acpiPm1Status_writew \n addr %x val:%x pm1_status:%x \n", addr, val,s->pm1_status); */ 1.179 } 1.180 @@ -384,7 +304,7 @@ static uint32_t acpiPm1Event_readl(void 1.181 { 1.182 PCIAcpiState *s = opaque; 1.183 uint32_t val; 1.184 - 1.185 + 1.186 val = s->pm1_status|(s->pm1_enable<<16); 1.187 /* printf("acpiPm1Event_readl \n addr %x val:%x\n", addr, val); */ 1.188 1.189 @@ -396,17 +316,21 @@ static void acpiPm1Timer_writel(void *op 1.190 PCIAcpiState *s = opaque; 1.191 1.192 s->pm1_timer = val; 1.193 -/* printf("acpiPm1Timer_writel \n addr %x val:%x\n", addr, val); */ 1.194 + s->old_vmck_ticks = qemu_get_clock(vm_clock) + 1.195 + muldiv64(val, FREQUENCE_PMTIMER, ticks_per_sec); 1.196 } 1.197 1.198 static uint32_t acpiPm1Timer_readl(void *opaque, uint32_t addr) 1.199 { 1.200 PCIAcpiState *s = opaque; 1.201 - uint32_t val; 1.202 + int64_t current_vmck_ticks = qemu_get_clock(vm_clock); 1.203 + int64_t vmck_ticks_delta = current_vmck_ticks - s->old_vmck_ticks; 1.204 1.205 - val = s->pm1_timer; 1.206 -/* printf("acpiPm1Timer_readl \n addr %x val:%x\n", addr, val); */ 1.207 - return val; 1.208 + if (s->old_vmck_ticks) 1.209 + s->pm1_timer += muldiv64(vmck_ticks_delta, FREQUENCE_PMTIMER, 1.210 + ticks_per_sec); 1.211 + s->old_vmck_ticks = current_vmck_ticks; 1.212 + return s->pm1_timer; 1.213 } 1.214 1.215 static void acpi_map(PCIDevice *pci_dev, int region_num, 1.216 @@ -414,7 +338,7 @@ static void acpi_map(PCIDevice *pci_dev, 1.217 { 1.218 PCIAcpiState *d = (PCIAcpiState *)pci_dev; 1.219 1.220 - printf("register acpi io \n"); 1.221 + printf("register acpi io\n"); 1.222 1.223 /* Byte access */ 1.224 register_ioport_write(addr, 1, 1, acpiPm1Status_writeb, d); 1.225 @@ -430,14 +354,14 @@ static void acpi_map(PCIDevice *pci_dev, 1.226 register_ioport_write(addr + 4, 1, 1, acpiPm1Control_writeb, d); 1.227 register_ioport_read(addr + 4, 1, 1, acpiPm1Control_readb, d); 1.228 register_ioport_write(addr + 4 + 1, 1, 1, acpiPm1ControlP1_writeb, d); 1.229 - register_ioport_read(addr + 4 +1, 1, 1, acpiPm1ControlP1_readb, d); 1.230 + register_ioport_read(addr + 4 +1, 1, 1, acpiPm1ControlP1_readb, d); 1.231 1.232 /* Word access */ 1.233 register_ioport_write(addr, 2, 2, acpiPm1Status_writew, d); 1.234 register_ioport_read(addr, 2, 2, acpiPm1Status_readw, d); 1.235 1.236 register_ioport_write(addr + 2, 2, 2, acpiPm1Enable_writew, d); 1.237 - register_ioport_read(addr + 2, 2, 2, acpiPm1Enable_readw, d); 1.238 + register_ioport_read(addr + 2, 2, 2, acpiPm1Enable_readw, d); 1.239 1.240 register_ioport_write(addr + 4, 2, 2, acpiPm1Control_writew, d); 1.241 register_ioport_read(addr + 4, 2, 2, acpiPm1Control_readw, d); 1.242 @@ -445,11 +369,10 @@ static void acpi_map(PCIDevice *pci_dev, 1.243 /* DWord access */ 1.244 register_ioport_write(addr, 4, 4, acpiPm1Event_writel, d); 1.245 register_ioport_read(addr, 4, 4, acpiPm1Event_readl, d); 1.246 - 1.247 + 1.248 register_ioport_write(addr + 8, 4, 4, acpiPm1Timer_writel, d); 1.249 register_ioport_read(addr + 8, 4, 4, acpiPm1Timer_readl, d); 1.250 } 1.251 - 1.252 1.253 /* PIIX4 acpi pci configuration space, func 3 */ 1.254 void pci_piix4_acpi_init(PCIBus *bus) 1.255 @@ -478,7 +401,5 @@ void pci_piix4_acpi_init(PCIBus *bus) 1.256 pci_register_io_region((PCIDevice *)d, 4, 0x10, 1.257 PCI_ADDRESS_SPACE_IO, acpi_map); 1.258 1.259 - pmtimer_state = pmtimer_init(); 1.260 - 1.261 - acpi_reset (d); 1.262 + acpi_reset(d); 1.263 }