]> git.proxmox.com Git - qemu.git/blob - hw/acpi_piix4.c
Use defines instead of numbers for pci hotplug sts bit
[qemu.git] / hw / acpi_piix4.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 "apm.h"
21 #include "pm_smbus.h"
22 #include "pci.h"
23 #include "acpi.h"
24 #include "sysemu.h"
25 #include "range.h"
26
27 //#define DEBUG
28
29 #ifdef DEBUG
30 # define PIIX4_DPRINTF(format, ...) printf(format, ## __VA_ARGS__)
31 #else
32 # define PIIX4_DPRINTF(format, ...) do { } while (0)
33 #endif
34
35 #define ACPI_DBG_IO_ADDR 0xb044
36
37 #define GPE_BASE 0xafe0
38 #define PCI_BASE 0xae00
39 #define PCI_EJ_BASE 0xae08
40
41 #define PIIX4_PCI_HOTPLUG_STATUS 2
42
43 struct gpe_regs {
44 uint16_t sts; /* status */
45 uint16_t en; /* enabled */
46 };
47
48 struct pci_status {
49 uint32_t up;
50 uint32_t down;
51 };
52
53 typedef struct PIIX4PMState {
54 PCIDevice dev;
55 uint16_t pmsts;
56 uint16_t pmen;
57 uint16_t pmcntrl;
58
59 APMState apm;
60
61 QEMUTimer *tmr_timer;
62 int64_t tmr_overflow_time;
63
64 PMSMBus smb;
65 uint32_t smb_io_base;
66
67 qemu_irq irq;
68 qemu_irq cmos_s3;
69 qemu_irq smi_irq;
70 int kvm_enabled;
71
72 /* for pci hotplug */
73 struct gpe_regs gpe;
74 struct pci_status pci0_status;
75 } PIIX4PMState;
76
77 static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s);
78
79 #define ACPI_ENABLE 0xf1
80 #define ACPI_DISABLE 0xf0
81
82 static uint32_t get_pmtmr(PIIX4PMState *s)
83 {
84 uint32_t d;
85 d = muldiv64(qemu_get_clock(vm_clock), PM_TIMER_FREQUENCY, get_ticks_per_sec());
86 return d & 0xffffff;
87 }
88
89 static int get_pmsts(PIIX4PMState *s)
90 {
91 int64_t d;
92
93 d = muldiv64(qemu_get_clock(vm_clock), PM_TIMER_FREQUENCY,
94 get_ticks_per_sec());
95 if (d >= s->tmr_overflow_time)
96 s->pmsts |= ACPI_BITMASK_TIMER_STATUS;
97 return s->pmsts;
98 }
99
100 static void pm_update_sci(PIIX4PMState *s)
101 {
102 int sci_level, pmsts;
103 int64_t expire_time;
104
105 pmsts = get_pmsts(s);
106 sci_level = (((pmsts & s->pmen) &
107 (ACPI_BITMASK_RT_CLOCK_ENABLE |
108 ACPI_BITMASK_POWER_BUTTON_ENABLE |
109 ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
110 ACPI_BITMASK_TIMER_ENABLE)) != 0);
111 qemu_set_irq(s->irq, sci_level);
112 /* schedule a timer interruption if needed */
113 if ((s->pmen & ACPI_BITMASK_TIMER_ENABLE) &&
114 !(pmsts & ACPI_BITMASK_TIMER_STATUS)) {
115 expire_time = muldiv64(s->tmr_overflow_time, get_ticks_per_sec(),
116 PM_TIMER_FREQUENCY);
117 qemu_mod_timer(s->tmr_timer, expire_time);
118 } else {
119 qemu_del_timer(s->tmr_timer);
120 }
121 }
122
123 static void pm_tmr_timer(void *opaque)
124 {
125 PIIX4PMState *s = opaque;
126 pm_update_sci(s);
127 }
128
129 static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
130 {
131 PIIX4PMState *s = opaque;
132 addr &= 0x3f;
133 switch(addr) {
134 case 0x00:
135 {
136 int64_t d;
137 int pmsts;
138 pmsts = get_pmsts(s);
139 if (pmsts & val & ACPI_BITMASK_TIMER_STATUS) {
140 /* if TMRSTS is reset, then compute the new overflow time */
141 d = muldiv64(qemu_get_clock(vm_clock), PM_TIMER_FREQUENCY,
142 get_ticks_per_sec());
143 s->tmr_overflow_time = (d + 0x800000LL) & ~0x7fffffLL;
144 }
145 s->pmsts &= ~val;
146 pm_update_sci(s);
147 }
148 break;
149 case 0x02:
150 s->pmen = val;
151 pm_update_sci(s);
152 break;
153 case 0x04:
154 {
155 int sus_typ;
156 s->pmcntrl = val & ~(ACPI_BITMASK_SLEEP_ENABLE);
157 if (val & ACPI_BITMASK_SLEEP_ENABLE) {
158 /* change suspend type */
159 sus_typ = (val >> 10) & 7;
160 switch(sus_typ) {
161 case 0: /* soft power off */
162 qemu_system_shutdown_request();
163 break;
164 case 1:
165 /* ACPI_BITMASK_WAKE_STATUS should be set on resume.
166 Pretend that resume was caused by power button */
167 s->pmsts |= (ACPI_BITMASK_WAKE_STATUS |
168 ACPI_BITMASK_POWER_BUTTON_STATUS);
169 qemu_system_reset_request();
170 if (s->cmos_s3) {
171 qemu_irq_raise(s->cmos_s3);
172 }
173 default:
174 break;
175 }
176 }
177 }
178 break;
179 default:
180 break;
181 }
182 PIIX4_DPRINTF("PM writew port=0x%04x val=0x%04x\n", addr, val);
183 }
184
185 static uint32_t pm_ioport_readw(void *opaque, uint32_t addr)
186 {
187 PIIX4PMState *s = opaque;
188 uint32_t val;
189
190 addr &= 0x3f;
191 switch(addr) {
192 case 0x00:
193 val = get_pmsts(s);
194 break;
195 case 0x02:
196 val = s->pmen;
197 break;
198 case 0x04:
199 val = s->pmcntrl;
200 break;
201 default:
202 val = 0;
203 break;
204 }
205 PIIX4_DPRINTF("PM readw port=0x%04x val=0x%04x\n", addr, val);
206 return val;
207 }
208
209 static void pm_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
210 {
211 // PIIX4PMState *s = opaque;
212 PIIX4_DPRINTF("PM writel port=0x%04x val=0x%08x\n", addr & 0x3f, val);
213 }
214
215 static uint32_t pm_ioport_readl(void *opaque, uint32_t addr)
216 {
217 PIIX4PMState *s = opaque;
218 uint32_t val;
219
220 addr &= 0x3f;
221 switch(addr) {
222 case 0x08:
223 val = get_pmtmr(s);
224 break;
225 default:
226 val = 0;
227 break;
228 }
229 PIIX4_DPRINTF("PM readl port=0x%04x val=0x%08x\n", addr, val);
230 return val;
231 }
232
233 static void apm_ctrl_changed(uint32_t val, void *arg)
234 {
235 PIIX4PMState *s = arg;
236
237 /* ACPI specs 3.0, 4.7.2.5 */
238 if (val == ACPI_ENABLE) {
239 s->pmcntrl |= ACPI_BITMASK_SCI_ENABLE;
240 } else if (val == ACPI_DISABLE) {
241 s->pmcntrl &= ~ACPI_BITMASK_SCI_ENABLE;
242 }
243
244 if (s->dev.config[0x5b] & (1 << 1)) {
245 if (s->smi_irq) {
246 qemu_irq_raise(s->smi_irq);
247 }
248 }
249 }
250
251 static void acpi_dbg_writel(void *opaque, uint32_t addr, uint32_t val)
252 {
253 PIIX4_DPRINTF("ACPI: DBG: 0x%08x\n", val);
254 }
255
256 static void pm_io_space_update(PIIX4PMState *s)
257 {
258 uint32_t pm_io_base;
259
260 if (s->dev.config[0x80] & 1) {
261 pm_io_base = le32_to_cpu(*(uint32_t *)(s->dev.config + 0x40));
262 pm_io_base &= 0xffc0;
263
264 /* XXX: need to improve memory and ioport allocation */
265 PIIX4_DPRINTF("PM: mapping to 0x%x\n", pm_io_base);
266 register_ioport_write(pm_io_base, 64, 2, pm_ioport_writew, s);
267 register_ioport_read(pm_io_base, 64, 2, pm_ioport_readw, s);
268 register_ioport_write(pm_io_base, 64, 4, pm_ioport_writel, s);
269 register_ioport_read(pm_io_base, 64, 4, pm_ioport_readl, s);
270 }
271 }
272
273 static void pm_write_config(PCIDevice *d,
274 uint32_t address, uint32_t val, int len)
275 {
276 pci_default_write_config(d, address, val, len);
277 if (range_covers_byte(address, len, 0x80))
278 pm_io_space_update((PIIX4PMState *)d);
279 }
280
281 static int vmstate_acpi_post_load(void *opaque, int version_id)
282 {
283 PIIX4PMState *s = opaque;
284
285 pm_io_space_update(s);
286 return 0;
287 }
288
289 static const VMStateDescription vmstate_gpe = {
290 .name = "gpe",
291 .version_id = 1,
292 .minimum_version_id = 1,
293 .minimum_version_id_old = 1,
294 .fields = (VMStateField []) {
295 VMSTATE_UINT16(sts, struct gpe_regs),
296 VMSTATE_UINT16(en, struct gpe_regs),
297 VMSTATE_END_OF_LIST()
298 }
299 };
300
301 static const VMStateDescription vmstate_pci_status = {
302 .name = "pci_status",
303 .version_id = 1,
304 .minimum_version_id = 1,
305 .minimum_version_id_old = 1,
306 .fields = (VMStateField []) {
307 VMSTATE_UINT32(up, struct pci_status),
308 VMSTATE_UINT32(down, struct pci_status),
309 VMSTATE_END_OF_LIST()
310 }
311 };
312
313 static const VMStateDescription vmstate_acpi = {
314 .name = "piix4_pm",
315 .version_id = 2,
316 .minimum_version_id = 1,
317 .minimum_version_id_old = 1,
318 .post_load = vmstate_acpi_post_load,
319 .fields = (VMStateField []) {
320 VMSTATE_PCI_DEVICE(dev, PIIX4PMState),
321 VMSTATE_UINT16(pmsts, PIIX4PMState),
322 VMSTATE_UINT16(pmen, PIIX4PMState),
323 VMSTATE_UINT16(pmcntrl, PIIX4PMState),
324 VMSTATE_STRUCT(apm, PIIX4PMState, 0, vmstate_apm, APMState),
325 VMSTATE_TIMER(tmr_timer, PIIX4PMState),
326 VMSTATE_INT64(tmr_overflow_time, PIIX4PMState),
327 VMSTATE_STRUCT(gpe, PIIX4PMState, 2, vmstate_gpe, struct gpe_regs),
328 VMSTATE_STRUCT(pci0_status, PIIX4PMState, 2, vmstate_pci_status,
329 struct pci_status),
330 VMSTATE_END_OF_LIST()
331 }
332 };
333
334 static void piix4_reset(void *opaque)
335 {
336 PIIX4PMState *s = opaque;
337 uint8_t *pci_conf = s->dev.config;
338
339 pci_conf[0x58] = 0;
340 pci_conf[0x59] = 0;
341 pci_conf[0x5a] = 0;
342 pci_conf[0x5b] = 0;
343
344 if (s->kvm_enabled) {
345 /* Mark SMM as already inited (until KVM supports SMM). */
346 pci_conf[0x5B] = 0x02;
347 }
348 }
349
350 static void piix4_powerdown(void *opaque, int irq, int power_failing)
351 {
352 PIIX4PMState *s = opaque;
353
354 if (!s) {
355 qemu_system_shutdown_request();
356 } else if (s->pmen & ACPI_BITMASK_POWER_BUTTON_ENABLE) {
357 s->pmsts |= ACPI_BITMASK_POWER_BUTTON_STATUS;
358 pm_update_sci(s);
359 }
360 }
361
362 static int piix4_pm_initfn(PCIDevice *dev)
363 {
364 PIIX4PMState *s = DO_UPCAST(PIIX4PMState, dev, dev);
365 uint8_t *pci_conf;
366
367 pci_conf = s->dev.config;
368 pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
369 pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371AB_3);
370 pci_conf[0x06] = 0x80;
371 pci_conf[0x07] = 0x02;
372 pci_conf[0x08] = 0x03; // revision number
373 pci_conf[0x09] = 0x00;
374 pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_OTHER);
375 pci_conf[0x3d] = 0x01; // interrupt pin 1
376
377 pci_conf[0x40] = 0x01; /* PM io base read only bit */
378
379 /* APM */
380 apm_init(&s->apm, apm_ctrl_changed, s);
381
382 register_ioport_write(ACPI_DBG_IO_ADDR, 4, 4, acpi_dbg_writel, s);
383
384 if (s->kvm_enabled) {
385 /* Mark SMM as already inited to prevent SMM from running. KVM does not
386 * support SMM mode. */
387 pci_conf[0x5B] = 0x02;
388 }
389
390 /* XXX: which specification is used ? The i82731AB has different
391 mappings */
392 pci_conf[0x5f] = (parallel_hds[0] != NULL ? 0x80 : 0) | 0x10;
393 pci_conf[0x63] = 0x60;
394 pci_conf[0x67] = (serial_hds[0] != NULL ? 0x08 : 0) |
395 (serial_hds[1] != NULL ? 0x90 : 0);
396
397 pci_conf[0x90] = s->smb_io_base | 1;
398 pci_conf[0x91] = s->smb_io_base >> 8;
399 pci_conf[0xd2] = 0x09;
400 register_ioport_write(s->smb_io_base, 64, 1, smb_ioport_writeb, &s->smb);
401 register_ioport_read(s->smb_io_base, 64, 1, smb_ioport_readb, &s->smb);
402
403 s->tmr_timer = qemu_new_timer(vm_clock, pm_tmr_timer, s);
404
405 qemu_system_powerdown = *qemu_allocate_irqs(piix4_powerdown, s, 1);
406
407 pm_smbus_init(&s->dev.qdev, &s->smb);
408 qemu_register_reset(piix4_reset, s);
409 piix4_acpi_system_hot_add_init(dev->bus, s);
410
411 return 0;
412 }
413
414 i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
415 qemu_irq sci_irq, qemu_irq cmos_s3, qemu_irq smi_irq,
416 int kvm_enabled)
417 {
418 PCIDevice *dev;
419 PIIX4PMState *s;
420
421 dev = pci_create(bus, devfn, "PIIX4_PM");
422 qdev_prop_set_uint32(&dev->qdev, "smb_io_base", smb_io_base);
423
424 s = DO_UPCAST(PIIX4PMState, dev, dev);
425 s->irq = sci_irq;
426 s->cmos_s3 = cmos_s3;
427 s->smi_irq = smi_irq;
428 s->kvm_enabled = kvm_enabled;
429
430 qdev_init_nofail(&dev->qdev);
431
432 return s->smb.smbus;
433 }
434
435 static PCIDeviceInfo piix4_pm_info = {
436 .qdev.name = "PIIX4_PM",
437 .qdev.desc = "PM",
438 .qdev.size = sizeof(PIIX4PMState),
439 .qdev.vmsd = &vmstate_acpi,
440 .init = piix4_pm_initfn,
441 .config_write = pm_write_config,
442 .qdev.props = (Property[]) {
443 DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0),
444 DEFINE_PROP_END_OF_LIST(),
445 }
446 };
447
448 static void piix4_pm_register(void)
449 {
450 pci_qdev_register(&piix4_pm_info);
451 }
452
453 device_init(piix4_pm_register);
454
455 static uint32_t gpe_read_val(uint16_t val, uint32_t addr)
456 {
457 if (addr & 1)
458 return (val >> 8) & 0xff;
459 return val & 0xff;
460 }
461
462 static uint32_t gpe_readb(void *opaque, uint32_t addr)
463 {
464 uint32_t val = 0;
465 struct gpe_regs *g = opaque;
466 switch (addr) {
467 case GPE_BASE:
468 case GPE_BASE + 1:
469 val = gpe_read_val(g->sts, addr);
470 break;
471 case GPE_BASE + 2:
472 case GPE_BASE + 3:
473 val = gpe_read_val(g->en, addr);
474 break;
475 default:
476 break;
477 }
478
479 PIIX4_DPRINTF("gpe read %x == %x\n", addr, val);
480 return val;
481 }
482
483 static void gpe_write_val(uint16_t *cur, int addr, uint32_t val)
484 {
485 if (addr & 1)
486 *cur = (*cur & 0xff) | (val << 8);
487 else
488 *cur = (*cur & 0xff00) | (val & 0xff);
489 }
490
491 static void gpe_reset_val(uint16_t *cur, int addr, uint32_t val)
492 {
493 uint16_t x1, x0 = val & 0xff;
494 int shift = (addr & 1) ? 8 : 0;
495
496 x1 = (*cur >> shift) & 0xff;
497
498 x1 = x1 & ~x0;
499
500 *cur = (*cur & (0xff << (8 - shift))) | (x1 << shift);
501 }
502
503 static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val)
504 {
505 struct gpe_regs *g = opaque;
506 switch (addr) {
507 case GPE_BASE:
508 case GPE_BASE + 1:
509 gpe_reset_val(&g->sts, addr, val);
510 break;
511 case GPE_BASE + 2:
512 case GPE_BASE + 3:
513 gpe_write_val(&g->en, addr, val);
514 break;
515 default:
516 break;
517 }
518
519 PIIX4_DPRINTF("gpe write %x <== %d\n", addr, val);
520 }
521
522 static uint32_t pcihotplug_read(void *opaque, uint32_t addr)
523 {
524 uint32_t val = 0;
525 struct pci_status *g = opaque;
526 switch (addr) {
527 case PCI_BASE:
528 val = g->up;
529 break;
530 case PCI_BASE + 4:
531 val = g->down;
532 break;
533 default:
534 break;
535 }
536
537 PIIX4_DPRINTF("pcihotplug read %x == %x\n", addr, val);
538 return val;
539 }
540
541 static void pcihotplug_write(void *opaque, uint32_t addr, uint32_t val)
542 {
543 struct pci_status *g = opaque;
544 switch (addr) {
545 case PCI_BASE:
546 g->up = val;
547 break;
548 case PCI_BASE + 4:
549 g->down = val;
550 break;
551 }
552
553 PIIX4_DPRINTF("pcihotplug write %x <== %d\n", addr, val);
554 }
555
556 static uint32_t pciej_read(void *opaque, uint32_t addr)
557 {
558 PIIX4_DPRINTF("pciej read %x\n", addr);
559 return 0;
560 }
561
562 static void pciej_write(void *opaque, uint32_t addr, uint32_t val)
563 {
564 BusState *bus = opaque;
565 DeviceState *qdev, *next;
566 PCIDevice *dev;
567 int slot = ffs(val) - 1;
568
569 QLIST_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
570 dev = DO_UPCAST(PCIDevice, qdev, qdev);
571 if (PCI_SLOT(dev->devfn) == slot) {
572 qdev_free(qdev);
573 }
574 }
575
576
577 PIIX4_DPRINTF("pciej write %x <== %d\n", addr, val);
578 }
579
580 static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev, int state);
581
582 static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
583 {
584 struct gpe_regs *gpe = &s->gpe;
585 struct pci_status *pci0_status = &s->pci0_status;
586
587 register_ioport_write(GPE_BASE, 4, 1, gpe_writeb, gpe);
588 register_ioport_read(GPE_BASE, 4, 1, gpe_readb, gpe);
589
590 register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, pci0_status);
591 register_ioport_read(PCI_BASE, 8, 4, pcihotplug_read, pci0_status);
592
593 register_ioport_write(PCI_EJ_BASE, 4, 4, pciej_write, bus);
594 register_ioport_read(PCI_EJ_BASE, 4, 4, pciej_read, bus);
595
596 pci_bus_hotplug(bus, piix4_device_hotplug, &s->dev.qdev);
597 }
598
599 static void enable_device(PIIX4PMState *s, int slot)
600 {
601 s->gpe.sts |= PIIX4_PCI_HOTPLUG_STATUS;
602 s->pci0_status.up |= (1 << slot);
603 }
604
605 static void disable_device(PIIX4PMState *s, int slot)
606 {
607 s->gpe.sts |= PIIX4_PCI_HOTPLUG_STATUS;
608 s->pci0_status.down |= (1 << slot);
609 }
610
611 static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev, int state)
612 {
613 int slot = PCI_SLOT(dev->devfn);
614 PIIX4PMState *s = DO_UPCAST(PIIX4PMState, dev,
615 DO_UPCAST(PCIDevice, qdev, qdev));
616
617 s->pci0_status.up = 0;
618 s->pci0_status.down = 0;
619 if (state) {
620 enable_device(s, slot);
621 } else {
622 disable_device(s, slot);
623 }
624 if (s->gpe.en & 2) {
625 qemu_set_irq(s->irq, 1);
626 qemu_set_irq(s->irq, 0);
627 }
628 return 0;
629 }