ia64/xen-unstable

changeset 10971: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>
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  }