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