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