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