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