Fix sci irq set when acpi timer about to wrap (Dor Laor, Yaniv Kamay).
[qemu] / hw / acpi.c
1 /*
2  * ACPI implementation
3  *
4  * Copyright (c) 2006 Fabrice Bellard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License version 2 as published by the Free Software Foundation.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19 #include "hw.h"
20 #include "pc.h"
21 #include "pci.h"
22 #include "qemu-timer.h"
23 #include "sysemu.h"
24 #include "i2c.h"
25 #include "smbus.h"
26
27 //#define DEBUG
28
29 /* i82731AB (PIIX4) compatible power management function */
30 #define PM_FREQ 3579545
31
32 #define ACPI_DBG_IO_ADDR  0xb044
33
34 typedef struct PIIX4PMState {
35     PCIDevice dev;
36     uint16_t pmsts;
37     uint16_t pmen;
38     uint16_t pmcntrl;
39     uint8_t apmc;
40     uint8_t apms;
41     QEMUTimer *tmr_timer;
42     int64_t tmr_overflow_time;
43     i2c_bus *smbus;
44     uint8_t smb_stat;
45     uint8_t smb_ctl;
46     uint8_t smb_cmd;
47     uint8_t smb_addr;
48     uint8_t smb_data0;
49     uint8_t smb_data1;
50     uint8_t smb_data[32];
51     uint8_t smb_index;
52     qemu_irq irq;
53     int64_t pmtmr;
54 } PIIX4PMState;
55
56 #define RTC_EN (1 << 10)
57 #define PWRBTN_EN (1 << 8)
58 #define GBL_EN (1 << 5)
59 #define TMROF_EN (1 << 0)
60 #define TIMER_OVERFLOW_CNT (1 << 23)
61 #define TIMER_MASK 0xffffffLL
62
63 #define SCI_EN (1 << 0)
64
65 #define SUS_EN (1 << 13)
66
67 #define ACPI_ENABLE 0xf1
68 #define ACPI_DISABLE 0xf0
69
70 #define SMBHSTSTS 0x00
71 #define SMBHSTCNT 0x02
72 #define SMBHSTCMD 0x03
73 #define SMBHSTADD 0x04
74 #define SMBHSTDAT0 0x05
75 #define SMBHSTDAT1 0x06
76 #define SMBBLKDAT 0x07
77
78 PIIX4PMState *pm_state;
79
80 static void update_pmtmr(PIIX4PMState *s)
81 {
82     int64_t pmtmr;
83
84     pmtmr = muldiv64(qemu_get_clock(vm_clock), PM_FREQ, ticks_per_sec)
85             & TIMER_MASK;
86
87     if (!(s->pmsts & TMROF_EN)) {
88         if ((pmtmr ^ s->pmtmr) & TIMER_OVERFLOW_CNT) {
89             s->pmsts |= TMROF_EN;
90             if (s->pmen & TMROF_EN)
91                 qemu_set_irq(s->irq, 1);
92         } else {
93             /* Calculate when the timer will neet to set
94              * the overflow bit again */
95             uint64_t delta = TIMER_OVERFLOW_CNT -
96                     (pmtmr & (TIMER_OVERFLOW_CNT - 1));
97
98             delta = muldiv64(delta, ticks_per_sec, PM_FREQ);
99             qemu_mod_timer(s->tmr_timer, qemu_get_clock(vm_clock) + delta);
100         }
101     }
102
103     s->pmtmr = pmtmr;
104 }
105
106 static uint32_t get_pmtmr(PIIX4PMState *s)
107 {
108     update_pmtmr(s);
109     return s->pmtmr & TIMER_MASK;
110 }
111
112
113 static int get_pmsts(PIIX4PMState *s)
114 {
115     /* Just increase the accurancy by double computing the timer value */
116     update_pmtmr(s);
117
118     return s->pmsts;
119 }
120
121 static void pm_update_sci(PIIX4PMState *s)
122 {
123     int sci_level;
124
125     sci_level = (((s->pmsts & s->pmen) & 
126                    (RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN)) != 0);
127     if (!sci_level)
128         qemu_set_irq(s->irq, sci_level);
129 }
130
131 static void pm_tmr_timer(void *opaque)
132 {
133     PIIX4PMState *s = opaque;
134     update_pmtmr(s);
135 }
136
137 static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
138 {
139     PIIX4PMState *s = opaque;
140     addr &= 0x3f;
141     switch(addr) {
142     case 0x00:
143         s->pmsts &= ~val;
144         update_pmtmr(s);
145         pm_update_sci(s);
146         break;
147     case 0x02:
148         s->pmen = val;
149         pm_update_sci(s);
150         break;
151     case 0x04:
152         {
153             int sus_typ;
154             s->pmcntrl = val & ~(SUS_EN);
155             if (val & SUS_EN) {
156                 /* change suspend type */
157                 sus_typ = (val >> 10) & 3;
158                 switch(sus_typ) {
159                 case 0: /* soft power off */
160                     qemu_system_shutdown_request();
161                     break;
162                 default:
163                     break;
164                 }
165             }
166         }
167         break;
168     default:
169         break;
170     }
171 #ifdef DEBUG
172     printf("PM writew port=0x%04x val=0x%04x\n", addr, val);
173 #endif
174 }
175
176 static uint32_t pm_ioport_readw(void *opaque, uint32_t addr)
177 {
178     PIIX4PMState *s = opaque;
179     uint32_t val;
180
181     addr &= 0x3f;
182     switch(addr) {
183     case 0x00:
184         val = get_pmsts(s);
185         break;
186     case 0x02:
187         val = s->pmen;
188         break;
189     case 0x04:
190         val = s->pmcntrl;
191         break;
192     default:
193         val = 0;
194         break;
195     }
196 #ifdef DEBUG
197     printf("PM readw port=0x%04x val=0x%04x\n", addr, val);
198 #endif
199     return val;
200 }
201
202 static void pm_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
203 {
204     //    PIIX4PMState *s = opaque;
205     addr &= 0x3f;
206 #ifdef DEBUG
207     printf("PM writel port=0x%04x val=0x%08x\n", addr, val);
208 #endif
209 }
210
211 static uint32_t pm_ioport_readl(void *opaque, uint32_t addr)
212 {
213     PIIX4PMState *s = opaque;
214     uint32_t val;
215
216     addr &= 0x3f;
217     switch(addr) {
218     case 0x08:
219         val = get_pmtmr(s);
220         break;
221     default:
222         val = 0;
223         break;
224     }
225 #ifdef DEBUG
226     printf("PM readl port=0x%04x val=0x%08x\n", addr, val);
227 #endif
228     return val;
229 }
230
231 static void pm_smi_writeb(void *opaque, uint32_t addr, uint32_t val)
232 {
233     PIIX4PMState *s = opaque;
234     addr &= 1;
235 #ifdef DEBUG
236     printf("pm_smi_writeb addr=0x%x val=0x%02x\n", addr, val);
237 #endif
238     if (addr == 0) {
239         s->apmc = val;
240
241         /* ACPI specs 3.0, 4.7.2.5 */
242         if (val == ACPI_ENABLE) {
243             s->pmcntrl |= SCI_EN;
244         } else if (val == ACPI_DISABLE) {
245             s->pmcntrl &= ~SCI_EN;
246         }
247
248         if (s->dev.config[0x5b] & (1 << 1)) {
249             cpu_interrupt(first_cpu, CPU_INTERRUPT_SMI);
250         }
251     } else {
252         s->apms = val;
253     }
254 }
255
256 static uint32_t pm_smi_readb(void *opaque, uint32_t addr)
257 {
258     PIIX4PMState *s = opaque;
259     uint32_t val;
260
261     addr &= 1;
262     if (addr == 0) {
263         val = s->apmc;
264     } else {
265         val = s->apms;
266     }
267 #ifdef DEBUG
268     printf("pm_smi_readb addr=0x%x val=0x%02x\n", addr, val);
269 #endif
270     return val;
271 }
272
273 static void acpi_dbg_writel(void *opaque, uint32_t addr, uint32_t val)
274 {
275 #if defined(DEBUG)
276     printf("ACPI: DBG: 0x%08x\n", val);
277 #endif
278 }
279
280 static void smb_transaction(PIIX4PMState *s)
281 {
282     uint8_t prot = (s->smb_ctl >> 2) & 0x07;
283     uint8_t read = s->smb_addr & 0x01;
284     uint8_t cmd = s->smb_cmd;
285     uint8_t addr = s->smb_addr >> 1;
286     i2c_bus *bus = s->smbus;
287
288 #ifdef DEBUG
289     printf("SMBus trans addr=0x%02x prot=0x%02x\n", addr, prot);
290 #endif
291     switch(prot) {
292     case 0x0:
293         smbus_quick_command(bus, addr, read);
294         break;
295     case 0x1:
296         if (read) {
297             s->smb_data0 = smbus_receive_byte(bus, addr);
298         } else {
299             smbus_send_byte(bus, addr, cmd);
300         }
301         break;
302     case 0x2:
303         if (read) {
304             s->smb_data0 = smbus_read_byte(bus, addr, cmd);
305         } else {
306             smbus_write_byte(bus, addr, cmd, s->smb_data0);
307         }
308         break;
309     case 0x3:
310         if (read) {
311             uint16_t val;
312             val = smbus_read_word(bus, addr, cmd);
313             s->smb_data0 = val;
314             s->smb_data1 = val >> 8;
315         } else {
316             smbus_write_word(bus, addr, cmd, (s->smb_data1 << 8) | s->smb_data0);
317         }
318         break;
319     case 0x5:
320         if (read) {
321             s->smb_data0 = smbus_read_block(bus, addr, cmd, s->smb_data);
322         } else {
323             smbus_write_block(bus, addr, cmd, s->smb_data, s->smb_data0);
324         }
325         break;
326     default:
327         goto error;
328     }
329     return;
330
331   error:
332     s->smb_stat |= 0x04;
333 }
334
335 static void smb_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
336 {
337     PIIX4PMState *s = opaque;
338     addr &= 0x3f;
339 #ifdef DEBUG
340     printf("SMB writeb port=0x%04x val=0x%02x\n", addr, val);
341 #endif
342     switch(addr) {
343     case SMBHSTSTS:
344         s->smb_stat = 0;
345         s->smb_index = 0;
346         break;
347     case SMBHSTCNT:
348         s->smb_ctl = val;
349         if (val & 0x40)
350             smb_transaction(s);
351         break;
352     case SMBHSTCMD:
353         s->smb_cmd = val;
354         break;
355     case SMBHSTADD:
356         s->smb_addr = val;
357         break;
358     case SMBHSTDAT0:
359         s->smb_data0 = val;
360         break;
361     case SMBHSTDAT1:
362         s->smb_data1 = val;
363         break;
364     case SMBBLKDAT:
365         s->smb_data[s->smb_index++] = val;
366         if (s->smb_index > 31)
367             s->smb_index = 0;
368         break;
369     default:
370         break;
371     }
372 }
373
374 static uint32_t smb_ioport_readb(void *opaque, uint32_t addr)
375 {
376     PIIX4PMState *s = opaque;
377     uint32_t val;
378
379     addr &= 0x3f;
380     switch(addr) {
381     case SMBHSTSTS:
382         val = s->smb_stat;
383         break;
384     case SMBHSTCNT:
385         s->smb_index = 0;
386         val = s->smb_ctl & 0x1f;
387         break;
388     case SMBHSTCMD:
389         val = s->smb_cmd;
390         break;
391     case SMBHSTADD:
392         val = s->smb_addr;
393         break;
394     case SMBHSTDAT0:
395         val = s->smb_data0;
396         break;
397     case SMBHSTDAT1:
398         val = s->smb_data1;
399         break;
400     case SMBBLKDAT:
401         val = s->smb_data[s->smb_index++];
402         if (s->smb_index > 31)
403             s->smb_index = 0;
404         break;
405     default:
406         val = 0;
407         break;
408     }
409 #ifdef DEBUG
410     printf("SMB readb port=0x%04x val=0x%02x\n", addr, val);
411 #endif
412     return val;
413 }
414
415 static void pm_io_space_update(PIIX4PMState *s)
416 {
417     uint32_t pm_io_base;
418
419     if (s->dev.config[0x80] & 1) {
420         pm_io_base = le32_to_cpu(*(uint32_t *)(s->dev.config + 0x40));
421         pm_io_base &= 0xffc0;
422
423         /* XXX: need to improve memory and ioport allocation */
424 #if defined(DEBUG)
425         printf("PM: mapping to 0x%x\n", pm_io_base);
426 #endif
427         register_ioport_write(pm_io_base, 64, 2, pm_ioport_writew, s);
428         register_ioport_read(pm_io_base, 64, 2, pm_ioport_readw, s);
429         register_ioport_write(pm_io_base, 64, 4, pm_ioport_writel, s);
430         register_ioport_read(pm_io_base, 64, 4, pm_ioport_readl, s);
431     }
432 }
433
434 static void pm_write_config(PCIDevice *d,
435                             uint32_t address, uint32_t val, int len)
436 {
437     pci_default_write_config(d, address, val, len);
438     if (address == 0x80)
439         pm_io_space_update((PIIX4PMState *)d);
440 }
441
442 static void pm_save(QEMUFile* f,void *opaque)
443 {
444     PIIX4PMState *s = opaque;
445
446     pci_device_save(&s->dev, f);
447
448     qemu_put_be16s(f, &s->pmsts);
449     qemu_put_be16s(f, &s->pmen);
450     qemu_put_be16s(f, &s->pmcntrl);
451     qemu_put_8s(f, &s->apmc);
452     qemu_put_8s(f, &s->apms);
453     qemu_put_timer(f, s->tmr_timer);
454     qemu_put_be64(f, s->tmr_overflow_time);
455 }
456
457 static int pm_load(QEMUFile* f,void* opaque,int version_id)
458 {
459     PIIX4PMState *s = opaque;
460     int ret;
461
462     if (version_id > 1)
463         return -EINVAL;
464
465     ret = pci_device_load(&s->dev, f);
466     if (ret < 0)
467         return ret;
468
469     qemu_get_be16s(f, &s->pmsts);
470     qemu_get_be16s(f, &s->pmen);
471     qemu_get_be16s(f, &s->pmcntrl);
472     qemu_get_8s(f, &s->apmc);
473     qemu_get_8s(f, &s->apms);
474     qemu_get_timer(f, s->tmr_timer);
475     s->tmr_overflow_time=qemu_get_be64(f);
476
477     pm_io_space_update(s);
478
479     return 0;
480 }
481
482 i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
483                        qemu_irq sci_irq)
484 {
485     PIIX4PMState *s;
486     uint8_t *pci_conf;
487
488     s = (PIIX4PMState *)pci_register_device(bus,
489                                          "PM", sizeof(PIIX4PMState),
490                                          devfn, NULL, pm_write_config);
491     pm_state = s;
492     pci_conf = s->dev.config;
493     pci_conf[0x00] = 0x86;
494     pci_conf[0x01] = 0x80;
495     pci_conf[0x02] = 0x13;
496     pci_conf[0x03] = 0x71;
497     pci_conf[0x06] = 0x80;
498     pci_conf[0x07] = 0x02;
499     pci_conf[0x08] = 0x03; // revision number
500     pci_conf[0x09] = 0x00;
501     pci_conf[0x0a] = 0x80; // other bridge device
502     pci_conf[0x0b] = 0x06; // bridge device
503     pci_conf[0x0e] = 0x00; // header_type
504     pci_conf[0x3d] = 0x01; // interrupt pin 1
505
506     pci_conf[0x40] = 0x01; /* PM io base read only bit */
507
508     register_ioport_write(0xb2, 2, 1, pm_smi_writeb, s);
509     register_ioport_read(0xb2, 2, 1, pm_smi_readb, s);
510
511     register_ioport_write(ACPI_DBG_IO_ADDR, 4, 4, acpi_dbg_writel, s);
512
513     /* XXX: which specification is used ? The i82731AB has different
514        mappings */
515     pci_conf[0x5f] = (parallel_hds[0] != NULL ? 0x80 : 0) | 0x10;
516     pci_conf[0x63] = 0x60;
517     pci_conf[0x67] = (serial_hds[0] != NULL ? 0x08 : 0) |
518         (serial_hds[1] != NULL ? 0x90 : 0);
519
520     pci_conf[0x90] = smb_io_base | 1;
521     pci_conf[0x91] = smb_io_base >> 8;
522     pci_conf[0xd2] = 0x09;
523     register_ioport_write(smb_io_base, 64, 1, smb_ioport_writeb, s);
524     register_ioport_read(smb_io_base, 64, 1, smb_ioport_readb, s);
525
526     s->tmr_timer = qemu_new_timer(vm_clock, pm_tmr_timer, s);
527
528     register_savevm("piix4_pm", 0, 1, pm_save, pm_load, s);
529
530     s->smbus = i2c_init_bus();
531     s->irq = sci_irq;
532     return s->smbus;
533 }
534
535 #if defined(TARGET_I386)
536 void qemu_system_powerdown(void)
537 {
538     if(pm_state->pmen & PWRBTN_EN) {
539         pm_state->pmsts |= PWRBTN_EN;
540         pm_update_sci(pm_state);
541     }
542 }
543 #endif