]> Git Repo - qemu.git/blob - hw/acpi.c
qdev/compat: virtio-console-pci 0.10 compatibility.
[qemu.git] / 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, see <http://www.gnu.org/licenses/>
17  */
18 #include "hw.h"
19 #include "pc.h"
20 #include "pci.h"
21 #include "qemu-timer.h"
22 #include "sysemu.h"
23 #include "i2c.h"
24 #include "smbus.h"
25 #include "kvm.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 RSM_STS (1 << 15)
56 #define PWRBTN_STS (1 << 8)
57 #define RTC_EN (1 << 10)
58 #define PWRBTN_EN (1 << 8)
59 #define GBL_EN (1 << 5)
60 #define TMROF_EN (1 << 0)
61
62 #define SCI_EN (1 << 0)
63
64 #define SUS_EN (1 << 13)
65
66 #define ACPI_ENABLE 0xf1
67 #define ACPI_DISABLE 0xf0
68
69 #define SMBHSTSTS 0x00
70 #define SMBHSTCNT 0x02
71 #define SMBHSTCMD 0x03
72 #define SMBHSTADD 0x04
73 #define SMBHSTDAT0 0x05
74 #define SMBHSTDAT1 0x06
75 #define SMBBLKDAT 0x07
76
77 static PIIX4PMState *pm_state;
78
79 static uint32_t get_pmtmr(PIIX4PMState *s)
80 {
81     uint32_t d;
82     d = muldiv64(qemu_get_clock(vm_clock), PM_FREQ, ticks_per_sec);
83     return d & 0xffffff;
84 }
85
86 static int get_pmsts(PIIX4PMState *s)
87 {
88     int64_t d;
89     int pmsts;
90     pmsts = s->pmsts;
91     d = muldiv64(qemu_get_clock(vm_clock), PM_FREQ, ticks_per_sec);
92     if (d >= s->tmr_overflow_time)
93         s->pmsts |= TMROF_EN;
94     return s->pmsts;
95 }
96
97 static void pm_update_sci(PIIX4PMState *s)
98 {
99     int sci_level, pmsts;
100     int64_t expire_time;
101
102     pmsts = get_pmsts(s);
103     sci_level = (((pmsts & s->pmen) &
104                   (RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN)) != 0);
105     qemu_set_irq(s->irq, sci_level);
106     /* schedule a timer interruption if needed */
107     if ((s->pmen & TMROF_EN) && !(pmsts & TMROF_EN)) {
108         expire_time = muldiv64(s->tmr_overflow_time, ticks_per_sec, PM_FREQ);
109         qemu_mod_timer(s->tmr_timer, expire_time);
110     } else {
111         qemu_del_timer(s->tmr_timer);
112     }
113 }
114
115 static void pm_tmr_timer(void *opaque)
116 {
117     PIIX4PMState *s = opaque;
118     pm_update_sci(s);
119 }
120
121 static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
122 {
123     PIIX4PMState *s = opaque;
124     addr &= 0x3f;
125     switch(addr) {
126     case 0x00:
127         {
128             int64_t d;
129             int pmsts;
130             pmsts = get_pmsts(s);
131             if (pmsts & val & TMROF_EN) {
132                 /* if TMRSTS is reset, then compute the new overflow time */
133                 d = muldiv64(qemu_get_clock(vm_clock), PM_FREQ, ticks_per_sec);
134                 s->tmr_overflow_time = (d + 0x800000LL) & ~0x7fffffLL;
135             }
136             s->pmsts &= ~val;
137             pm_update_sci(s);
138         }
139         break;
140     case 0x02:
141         s->pmen = val;
142         pm_update_sci(s);
143         break;
144     case 0x04:
145         {
146             int sus_typ;
147             s->pmcntrl = val & ~(SUS_EN);
148             if (val & SUS_EN) {
149                 /* change suspend type */
150                 sus_typ = (val >> 10) & 7;
151                 switch(sus_typ) {
152                 case 0: /* soft power off */
153                     qemu_system_shutdown_request();
154                     break;
155                 case 1:
156                     /* RSM_STS should be set on resume. Pretend that resume
157                        was caused by power button */
158                     s->pmsts |= (RSM_STS | PWRBTN_STS);
159                     qemu_system_reset_request();
160 #if defined(TARGET_I386)
161                     cmos_set_s3_resume();
162 #endif
163                 default:
164                     break;
165                 }
166             }
167         }
168         break;
169     default:
170         break;
171     }
172 #ifdef DEBUG
173     printf("PM writew port=0x%04x val=0x%04x\n", addr, val);
174 #endif
175 }
176
177 static uint32_t pm_ioport_readw(void *opaque, uint32_t addr)
178 {
179     PIIX4PMState *s = opaque;
180     uint32_t val;
181
182     addr &= 0x3f;
183     switch(addr) {
184     case 0x00:
185         val = get_pmsts(s);
186         break;
187     case 0x02:
188         val = s->pmen;
189         break;
190     case 0x04:
191         val = s->pmcntrl;
192         break;
193     default:
194         val = 0;
195         break;
196     }
197 #ifdef DEBUG
198     printf("PM readw port=0x%04x val=0x%04x\n", addr, val);
199 #endif
200     return val;
201 }
202
203 static void pm_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
204 {
205     //    PIIX4PMState *s = opaque;
206     addr &= 0x3f;
207 #ifdef DEBUG
208     printf("PM writel port=0x%04x val=0x%08x\n", addr, val);
209 #endif
210 }
211
212 static uint32_t pm_ioport_readl(void *opaque, uint32_t addr)
213 {
214     PIIX4PMState *s = opaque;
215     uint32_t val;
216
217     addr &= 0x3f;
218     switch(addr) {
219     case 0x08:
220         val = get_pmtmr(s);
221         break;
222     default:
223         val = 0;
224         break;
225     }
226 #ifdef DEBUG
227     printf("PM readl port=0x%04x val=0x%08x\n", addr, val);
228 #endif
229     return val;
230 }
231
232 static void pm_smi_writeb(void *opaque, uint32_t addr, uint32_t val)
233 {
234     PIIX4PMState *s = opaque;
235     addr &= 1;
236 #ifdef DEBUG
237     printf("pm_smi_writeb addr=0x%x val=0x%02x\n", addr, val);
238 #endif
239     if (addr == 0) {
240         s->apmc = val;
241
242         /* ACPI specs 3.0, 4.7.2.5 */
243         if (val == ACPI_ENABLE) {
244             s->pmcntrl |= SCI_EN;
245         } else if (val == ACPI_DISABLE) {
246             s->pmcntrl &= ~SCI_EN;
247         }
248
249         if (s->dev.config[0x5b] & (1 << 1)) {
250             cpu_interrupt(first_cpu, CPU_INTERRUPT_SMI);
251         }
252     } else {
253         s->apms = val;
254     }
255 }
256
257 static uint32_t pm_smi_readb(void *opaque, uint32_t addr)
258 {
259     PIIX4PMState *s = opaque;
260     uint32_t val;
261
262     addr &= 1;
263     if (addr == 0) {
264         val = s->apmc;
265     } else {
266         val = s->apms;
267     }
268 #ifdef DEBUG
269     printf("pm_smi_readb addr=0x%x val=0x%02x\n", addr, val);
270 #endif
271     return val;
272 }
273
274 static void acpi_dbg_writel(void *opaque, uint32_t addr, uint32_t val)
275 {
276 #if defined(DEBUG)
277     printf("ACPI: DBG: 0x%08x\n", val);
278 #endif
279 }
280
281 static void smb_transaction(PIIX4PMState *s)
282 {
283     uint8_t prot = (s->smb_ctl >> 2) & 0x07;
284     uint8_t read = s->smb_addr & 0x01;
285     uint8_t cmd = s->smb_cmd;
286     uint8_t addr = s->smb_addr >> 1;
287     i2c_bus *bus = s->smbus;
288
289 #ifdef DEBUG
290     printf("SMBus trans addr=0x%02x prot=0x%02x\n", addr, prot);
291 #endif
292     switch(prot) {
293     case 0x0:
294         smbus_quick_command(bus, addr, read);
295         break;
296     case 0x1:
297         if (read) {
298             s->smb_data0 = smbus_receive_byte(bus, addr);
299         } else {
300             smbus_send_byte(bus, addr, cmd);
301         }
302         break;
303     case 0x2:
304         if (read) {
305             s->smb_data0 = smbus_read_byte(bus, addr, cmd);
306         } else {
307             smbus_write_byte(bus, addr, cmd, s->smb_data0);
308         }
309         break;
310     case 0x3:
311         if (read) {
312             uint16_t val;
313             val = smbus_read_word(bus, addr, cmd);
314             s->smb_data0 = val;
315             s->smb_data1 = val >> 8;
316         } else {
317             smbus_write_word(bus, addr, cmd, (s->smb_data1 << 8) | s->smb_data0);
318         }
319         break;
320     case 0x5:
321         if (read) {
322             s->smb_data0 = smbus_read_block(bus, addr, cmd, s->smb_data);
323         } else {
324             smbus_write_block(bus, addr, cmd, s->smb_data, s->smb_data0);
325         }
326         break;
327     default:
328         goto error;
329     }
330     return;
331
332   error:
333     s->smb_stat |= 0x04;
334 }
335
336 static void smb_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
337 {
338     PIIX4PMState *s = opaque;
339     addr &= 0x3f;
340 #ifdef DEBUG
341     printf("SMB writeb port=0x%04x val=0x%02x\n", addr, val);
342 #endif
343     switch(addr) {
344     case SMBHSTSTS:
345         s->smb_stat = 0;
346         s->smb_index = 0;
347         break;
348     case SMBHSTCNT:
349         s->smb_ctl = val;
350         if (val & 0x40)
351             smb_transaction(s);
352         break;
353     case SMBHSTCMD:
354         s->smb_cmd = val;
355         break;
356     case SMBHSTADD:
357         s->smb_addr = val;
358         break;
359     case SMBHSTDAT0:
360         s->smb_data0 = val;
361         break;
362     case SMBHSTDAT1:
363         s->smb_data1 = val;
364         break;
365     case SMBBLKDAT:
366         s->smb_data[s->smb_index++] = val;
367         if (s->smb_index > 31)
368             s->smb_index = 0;
369         break;
370     default:
371         break;
372     }
373 }
374
375 static uint32_t smb_ioport_readb(void *opaque, uint32_t addr)
376 {
377     PIIX4PMState *s = opaque;
378     uint32_t val;
379
380     addr &= 0x3f;
381     switch(addr) {
382     case SMBHSTSTS:
383         val = s->smb_stat;
384         break;
385     case SMBHSTCNT:
386         s->smb_index = 0;
387         val = s->smb_ctl & 0x1f;
388         break;
389     case SMBHSTCMD:
390         val = s->smb_cmd;
391         break;
392     case SMBHSTADD:
393         val = s->smb_addr;
394         break;
395     case SMBHSTDAT0:
396         val = s->smb_data0;
397         break;
398     case SMBHSTDAT1:
399         val = s->smb_data1;
400         break;
401     case SMBBLKDAT:
402         val = s->smb_data[s->smb_index++];
403         if (s->smb_index > 31)
404             s->smb_index = 0;
405         break;
406     default:
407         val = 0;
408         break;
409     }
410 #ifdef DEBUG
411     printf("SMB readb port=0x%04x val=0x%02x\n", addr, val);
412 #endif
413     return val;
414 }
415
416 static void pm_io_space_update(PIIX4PMState *s)
417 {
418     uint32_t pm_io_base;
419
420     if (s->dev.config[0x80] & 1) {
421         pm_io_base = le32_to_cpu(*(uint32_t *)(s->dev.config + 0x40));
422         pm_io_base &= 0xffc0;
423
424         /* XXX: need to improve memory and ioport allocation */
425 #if defined(DEBUG)
426         printf("PM: mapping to 0x%x\n", pm_io_base);
427 #endif
428         register_ioport_write(pm_io_base, 64, 2, pm_ioport_writew, s);
429         register_ioport_read(pm_io_base, 64, 2, pm_ioport_readw, s);
430         register_ioport_write(pm_io_base, 64, 4, pm_ioport_writel, s);
431         register_ioport_read(pm_io_base, 64, 4, pm_ioport_readl, s);
432     }
433 }
434
435 static void pm_write_config(PCIDevice *d,
436                             uint32_t address, uint32_t val, int len)
437 {
438     pci_default_write_config(d, address, val, len);
439     if (address == 0x80)
440         pm_io_space_update((PIIX4PMState *)d);
441 }
442
443 static void pm_save(QEMUFile* f,void *opaque)
444 {
445     PIIX4PMState *s = opaque;
446
447     pci_device_save(&s->dev, f);
448
449     qemu_put_be16s(f, &s->pmsts);
450     qemu_put_be16s(f, &s->pmen);
451     qemu_put_be16s(f, &s->pmcntrl);
452     qemu_put_8s(f, &s->apmc);
453     qemu_put_8s(f, &s->apms);
454     qemu_put_timer(f, s->tmr_timer);
455     qemu_put_be64(f, s->tmr_overflow_time);
456 }
457
458 static int pm_load(QEMUFile* f,void* opaque,int version_id)
459 {
460     PIIX4PMState *s = opaque;
461     int ret;
462
463     if (version_id > 1)
464         return -EINVAL;
465
466     ret = pci_device_load(&s->dev, f);
467     if (ret < 0)
468         return ret;
469
470     qemu_get_be16s(f, &s->pmsts);
471     qemu_get_be16s(f, &s->pmen);
472     qemu_get_be16s(f, &s->pmcntrl);
473     qemu_get_8s(f, &s->apmc);
474     qemu_get_8s(f, &s->apms);
475     qemu_get_timer(f, s->tmr_timer);
476     s->tmr_overflow_time=qemu_get_be64(f);
477
478     pm_io_space_update(s);
479
480     return 0;
481 }
482
483 static void piix4_reset(void *opaque)
484 {
485     PIIX4PMState *s = opaque;
486     uint8_t *pci_conf = s->dev.config;
487
488     pci_conf[0x58] = 0;
489     pci_conf[0x59] = 0;
490     pci_conf[0x5a] = 0;
491     pci_conf[0x5b] = 0;
492
493     if (kvm_enabled()) {
494         /* Mark SMM as already inited (until KVM supports SMM). */
495         pci_conf[0x5B] = 0x02;
496     }
497 }
498
499 i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
500                        qemu_irq sci_irq)
501 {
502     PIIX4PMState *s;
503     uint8_t *pci_conf;
504
505     s = (PIIX4PMState *)pci_register_device(bus,
506                                          "PM", sizeof(PIIX4PMState),
507                                          devfn, NULL, pm_write_config);
508     pm_state = s;
509     pci_conf = s->dev.config;
510     pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
511     pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371AB_3);
512     pci_conf[0x06] = 0x80;
513     pci_conf[0x07] = 0x02;
514     pci_conf[0x08] = 0x03; // revision number
515     pci_conf[0x09] = 0x00;
516     pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_OTHER);
517     pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
518     pci_conf[0x3d] = 0x01; // interrupt pin 1
519
520     pci_conf[0x40] = 0x01; /* PM io base read only bit */
521
522     register_ioport_write(0xb2, 2, 1, pm_smi_writeb, s);
523     register_ioport_read(0xb2, 2, 1, pm_smi_readb, s);
524
525     register_ioport_write(ACPI_DBG_IO_ADDR, 4, 4, acpi_dbg_writel, s);
526
527     if (kvm_enabled()) {
528         /* Mark SMM as already inited to prevent SMM from running.  KVM does not
529          * support SMM mode. */
530         pci_conf[0x5B] = 0x02;
531     }
532
533     /* XXX: which specification is used ? The i82731AB has different
534        mappings */
535     pci_conf[0x5f] = (parallel_hds[0] != NULL ? 0x80 : 0) | 0x10;
536     pci_conf[0x63] = 0x60;
537     pci_conf[0x67] = (serial_hds[0] != NULL ? 0x08 : 0) |
538         (serial_hds[1] != NULL ? 0x90 : 0);
539
540     pci_conf[0x90] = smb_io_base | 1;
541     pci_conf[0x91] = smb_io_base >> 8;
542     pci_conf[0xd2] = 0x09;
543     register_ioport_write(smb_io_base, 64, 1, smb_ioport_writeb, s);
544     register_ioport_read(smb_io_base, 64, 1, smb_ioport_readb, s);
545
546     s->tmr_timer = qemu_new_timer(vm_clock, pm_tmr_timer, s);
547
548     register_savevm("piix4_pm", 0, 1, pm_save, pm_load, s);
549
550     s->smbus = i2c_init_bus(NULL, "i2c");
551     s->irq = sci_irq;
552     qemu_register_reset(piix4_reset, s);
553
554     return s->smbus;
555 }
556
557 #if defined(TARGET_I386)
558 void qemu_system_powerdown(void)
559 {
560     if (!pm_state) {
561         qemu_system_shutdown_request();
562     } else if (pm_state->pmen & PWRBTN_EN) {
563         pm_state->pmsts |= PWRBTN_EN;
564         pm_update_sci(pm_state);
565     }
566 }
567 #endif
568
569 #define GPE_BASE 0xafe0
570 #define PCI_BASE 0xae00
571 #define PCI_EJ_BASE 0xae08
572
573 struct gpe_regs {
574     uint16_t sts; /* status */
575     uint16_t en;  /* enabled */
576 };
577
578 struct pci_status {
579     uint32_t up;
580     uint32_t down;
581 };
582
583 static struct gpe_regs gpe;
584 static struct pci_status pci0_status;
585
586 static uint32_t gpe_read_val(uint16_t val, uint32_t addr)
587 {
588     if (addr & 1)
589         return (val >> 8) & 0xff;
590     return val & 0xff;
591 }
592
593 static uint32_t gpe_readb(void *opaque, uint32_t addr)
594 {
595     uint32_t val = 0;
596     struct gpe_regs *g = opaque;
597     switch (addr) {
598         case GPE_BASE:
599         case GPE_BASE + 1:
600             val = gpe_read_val(g->sts, addr);
601             break;
602         case GPE_BASE + 2:
603         case GPE_BASE + 3:
604             val = gpe_read_val(g->en, addr);
605             break;
606         default:
607             break;
608     }
609
610 #if defined(DEBUG)
611     printf("gpe read %x == %x\n", addr, val);
612 #endif
613     return val;
614 }
615
616 static void gpe_write_val(uint16_t *cur, int addr, uint32_t val)
617 {
618     if (addr & 1)
619         *cur = (*cur & 0xff) | (val << 8);
620     else
621         *cur = (*cur & 0xff00) | (val & 0xff);
622 }
623
624 static void gpe_reset_val(uint16_t *cur, int addr, uint32_t val)
625 {
626     uint16_t x1, x0 = val & 0xff;
627     int shift = (addr & 1) ? 8 : 0;
628
629     x1 = (*cur >> shift) & 0xff;
630
631     x1 = x1 & ~x0;
632
633     *cur = (*cur & (0xff << (8 - shift))) | (x1 << shift);
634 }
635
636 static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val)
637 {
638     struct gpe_regs *g = opaque;
639     switch (addr) {
640         case GPE_BASE:
641         case GPE_BASE + 1:
642             gpe_reset_val(&g->sts, addr, val);
643             break;
644         case GPE_BASE + 2:
645         case GPE_BASE + 3:
646             gpe_write_val(&g->en, addr, val);
647             break;
648         default:
649             break;
650    }
651
652 #if defined(DEBUG)
653     printf("gpe write %x <== %d\n", addr, val);
654 #endif
655 }
656
657 static uint32_t pcihotplug_read(void *opaque, uint32_t addr)
658 {
659     uint32_t val = 0;
660     struct pci_status *g = opaque;
661     switch (addr) {
662         case PCI_BASE:
663             val = g->up;
664             break;
665         case PCI_BASE + 4:
666             val = g->down;
667             break;
668         default:
669             break;
670     }
671
672 #if defined(DEBUG)
673     printf("pcihotplug read %x == %x\n", addr, val);
674 #endif
675     return val;
676 }
677
678 static void pcihotplug_write(void *opaque, uint32_t addr, uint32_t val)
679 {
680     struct pci_status *g = opaque;
681     switch (addr) {
682         case PCI_BASE:
683             g->up = val;
684             break;
685         case PCI_BASE + 4:
686             g->down = val;
687             break;
688    }
689
690 #if defined(DEBUG)
691     printf("pcihotplug write %x <== %d\n", addr, val);
692 #endif
693 }
694
695 static uint32_t pciej_read(void *opaque, uint32_t addr)
696 {
697 #if defined(DEBUG)
698     printf("pciej read %x\n", addr);
699 #endif
700     return 0;
701 }
702
703 static void pciej_write(void *opaque, uint32_t addr, uint32_t val)
704 {
705 #if defined (TARGET_I386)
706     int slot = ffs(val) - 1;
707
708     pci_device_hot_remove_success(0, slot);
709 #endif
710
711 #if defined(DEBUG)
712     printf("pciej write %x <== %d\n", addr, val);
713 #endif
714 }
715
716 static void piix4_device_hot_add(int bus, int slot, int state);
717
718 void piix4_acpi_system_hot_add_init(void)
719 {
720     register_ioport_write(GPE_BASE, 4, 1, gpe_writeb, &gpe);
721     register_ioport_read(GPE_BASE, 4, 1,  gpe_readb, &gpe);
722
723     register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, &pci0_status);
724     register_ioport_read(PCI_BASE, 8, 4,  pcihotplug_read, &pci0_status);
725
726     register_ioport_write(PCI_EJ_BASE, 4, 4, pciej_write, NULL);
727     register_ioport_read(PCI_EJ_BASE, 4, 4,  pciej_read, NULL);
728
729     qemu_system_device_hot_add_register(piix4_device_hot_add);
730 }
731
732 static void enable_device(struct pci_status *p, struct gpe_regs *g, int slot)
733 {
734     g->sts |= 2;
735     p->up |= (1 << slot);
736 }
737
738 static void disable_device(struct pci_status *p, struct gpe_regs *g, int slot)
739 {
740     g->sts |= 2;
741     p->down |= (1 << slot);
742 }
743
744 static void piix4_device_hot_add(int bus, int slot, int state)
745 {
746     pci0_status.up = 0;
747     pci0_status.down = 0;
748     if (state)
749         enable_device(&pci0_status, &gpe, slot);
750     else
751         disable_device(&pci0_status, &gpe, slot);
752     if (gpe.en & 2) {
753         qemu_set_irq(pm_state->irq, 1);
754         qemu_set_irq(pm_state->irq, 0);
755     }
756 }
757
758 static qemu_system_device_hot_add_t device_hot_add_callback;
759 void qemu_system_device_hot_add_register(qemu_system_device_hot_add_t callback)
760 {
761     device_hot_add_callback = callback;
762 }
763
764 void qemu_system_device_hot_add(int pcibus, int slot, int state)
765 {
766     if (device_hot_add_callback)
767         device_hot_add_callback(pcibus, slot, state);
768 }
769
770 struct acpi_table_header
771 {
772     char signature [4];    /* ACPI signature (4 ASCII characters) */
773     uint32_t length;          /* Length of table, in bytes, including header */
774     uint8_t revision;         /* ACPI Specification minor version # */
775     uint8_t checksum;         /* To make sum of entire table == 0 */
776     char oem_id [6];       /* OEM identification */
777     char oem_table_id [8]; /* OEM table identification */
778     uint32_t oem_revision;    /* OEM revision number */
779     char asl_compiler_id [4]; /* ASL compiler vendor ID */
780     uint32_t asl_compiler_revision; /* ASL compiler revision number */
781 } __attribute__((packed));
782
783 char *acpi_tables;
784 size_t acpi_tables_len;
785
786 static int acpi_checksum(const uint8_t *data, int len)
787 {
788     int sum, i;
789     sum = 0;
790     for(i = 0; i < len; i++)
791         sum += data[i];
792     return (-sum) & 0xff;
793 }
794
795 int acpi_table_add(const char *t)
796 {
797     static const char *dfl_id = "QEMUQEMU";
798     char buf[1024], *p, *f;
799     struct acpi_table_header acpi_hdr;
800     unsigned long val;
801     size_t off;
802
803     memset(&acpi_hdr, 0, sizeof(acpi_hdr));
804   
805     if (get_param_value(buf, sizeof(buf), "sig", t)) {
806         strncpy(acpi_hdr.signature, buf, 4);
807     } else {
808         strncpy(acpi_hdr.signature, dfl_id, 4);
809     }
810     if (get_param_value(buf, sizeof(buf), "rev", t)) {
811         val = strtoul(buf, &p, 10);
812         if (val > 255 || *p != '\0')
813             goto out;
814     } else {
815         val = 1;
816     }
817     acpi_hdr.revision = (int8_t)val;
818
819     if (get_param_value(buf, sizeof(buf), "oem_id", t)) {
820         strncpy(acpi_hdr.oem_id, buf, 6);
821     } else {
822         strncpy(acpi_hdr.oem_id, dfl_id, 6);
823     }
824
825     if (get_param_value(buf, sizeof(buf), "oem_table_id", t)) {
826         strncpy(acpi_hdr.oem_table_id, buf, 8);
827     } else {
828         strncpy(acpi_hdr.oem_table_id, dfl_id, 8);
829     }
830
831     if (get_param_value(buf, sizeof(buf), "oem_rev", t)) {
832         val = strtol(buf, &p, 10);
833         if(*p != '\0')
834             goto out;
835     } else {
836         val = 1;
837     }
838     acpi_hdr.oem_revision = cpu_to_le32(val);
839
840     if (get_param_value(buf, sizeof(buf), "asl_compiler_id", t)) {
841         strncpy(acpi_hdr.asl_compiler_id, buf, 4);
842     } else {
843         strncpy(acpi_hdr.asl_compiler_id, dfl_id, 4);
844     }
845
846     if (get_param_value(buf, sizeof(buf), "asl_compiler_rev", t)) {
847         val = strtol(buf, &p, 10);
848         if(*p != '\0')
849             goto out;
850     } else {
851         val = 1;
852     }
853     acpi_hdr.asl_compiler_revision = cpu_to_le32(val);
854     
855     if (!get_param_value(buf, sizeof(buf), "data", t)) {
856          buf[0] = '\0';
857     }
858
859     acpi_hdr.length = sizeof(acpi_hdr);
860
861     f = buf;
862     while (buf[0]) {
863         struct stat s;
864         char *n = strchr(f, ':');
865         if (n)
866             *n = '\0';
867         if(stat(f, &s) < 0) {
868             fprintf(stderr, "Can't stat file '%s': %s\n", f, strerror(errno));
869             goto out;
870         }
871         acpi_hdr.length += s.st_size;
872         if (!n)
873             break;
874         *n = ':';
875         f = n + 1;
876     }
877
878     if (!acpi_tables) {
879         acpi_tables_len = sizeof(uint16_t);
880         acpi_tables = qemu_mallocz(acpi_tables_len);
881     }
882     p = acpi_tables + acpi_tables_len;
883     acpi_tables_len += sizeof(uint16_t) + acpi_hdr.length;
884     acpi_tables = qemu_realloc(acpi_tables, acpi_tables_len);
885
886     acpi_hdr.length = cpu_to_le32(acpi_hdr.length);
887     *(uint16_t*)p = acpi_hdr.length;
888     p += sizeof(uint16_t);
889     memcpy(p, &acpi_hdr, sizeof(acpi_hdr));
890     off = sizeof(acpi_hdr);
891
892     f = buf;
893     while (buf[0]) {
894         struct stat s;
895         int fd;
896         char *n = strchr(f, ':');
897         if (n)
898             *n = '\0';
899         fd = open(f, O_RDONLY);
900
901         if(fd < 0)
902             goto out;
903         if(fstat(fd, &s) < 0) {
904             close(fd);
905             goto out;
906         }
907
908         do {
909             int r;
910             r = read(fd, p + off, s.st_size);
911             if (r > 0) {
912                 off += r;
913                 s.st_size -= r;
914             } else if ((r < 0 && errno != EINTR) || r == 0) {
915                 close(fd);
916                 goto out;
917             }
918         } while(s.st_size);
919
920         close(fd);
921         if (!n)
922             break;
923         f = n + 1;
924     }
925
926     ((struct acpi_table_header*)p)->checksum = acpi_checksum((uint8_t*)p, off);
927     /* increase number of tables */
928     (*(uint16_t*)acpi_tables) =
929             cpu_to_le32(le32_to_cpu(*(uint16_t*)acpi_tables) + 1);
930     return 0;
931 out:
932     if (acpi_tables) {
933         free(acpi_tables);
934         acpi_tables = NULL;
935     }
936     return -1;
937 }
This page took 0.077478 seconds and 4 git commands to generate.