]> git.proxmox.com Git - mirror_qemu.git/blame - hw/acpi/piix4.c
i2c: Rename i2c_bus to I2CBus
[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/>
6b620ca3
PB
17 *
18 * Contributions after 2012-01-13 are licensed under the terms of the
19 * GNU GPL, version 2 or (at your option) any later version.
93d89f63 20 */
83c9f4ca 21#include "hw/hw.h"
0d09e41a
PB
22#include "hw/i386/pc.h"
23#include "hw/isa/apm.h"
24#include "hw/i2c/pm_smbus.h"
83c9f4ca 25#include "hw/pci/pci.h"
0d09e41a 26#include "hw/acpi/acpi.h"
9c17d615 27#include "sysemu/sysemu.h"
1de7afc9 28#include "qemu/range.h"
022c62cb 29#include "exec/ioport.h"
0d09e41a 30#include "hw/nvram/fw_cfg.h"
022c62cb 31#include "exec/address-spaces.h"
277e9340 32#include "hw/acpi/piix4.h"
9e047b98 33#include "hw/acpi/pcihp.h"
81cea5e7 34#include "hw/acpi/cpu_hotplug.h"
93d89f63
IY
35
36//#define DEBUG
37
50d8ff8b
IY
38#ifdef DEBUG
39# define PIIX4_DPRINTF(format, ...) printf(format, ## __VA_ARGS__)
40#else
41# define PIIX4_DPRINTF(format, ...) do { } while (0)
42#endif
43
ac404095 44#define GPE_BASE 0xafe0
23910d3f 45#define GPE_LEN 4
c177684c
GH
46
47#define PCI_HOTPLUG_ADDR 0xae00
48#define PCI_HOTPLUG_SIZE 0x000f
ba737541
AW
49#define PCI_UP_BASE 0xae00
50#define PCI_DOWN_BASE 0xae04
ac404095 51#define PCI_EJ_BASE 0xae08
668643b0 52#define PCI_RMV_BASE 0xae0c
ac404095 53
4441a287
GN
54#define PIIX4_PCI_HOTPLUG_STATUS 2
55
ac404095 56struct pci_status {
7faa8075 57 uint32_t up; /* deprecated, maintained for migration compatibility */
ac404095
IY
58 uint32_t down;
59};
60
93d89f63 61typedef struct PIIX4PMState {
6a6b5580
AF
62 /*< private >*/
63 PCIDevice parent_obj;
64 /*< public >*/
56e5b2a1 65
af11110b 66 MemoryRegion io;
277e9340
MT
67 uint32_t io_base;
68
b65b93f2 69 MemoryRegion io_gpe;
355bf2e5 70 ACPIREGS ar;
93d89f63
IY
71
72 APMState apm;
73
93d89f63 74 PMSMBus smb;
e8ec0571 75 uint32_t smb_io_base;
93d89f63
IY
76
77 qemu_irq irq;
93d89f63
IY
78 qemu_irq smi_irq;
79 int kvm_enabled;
6141dbfe 80 Notifier machine_ready;
d010f91c 81 Notifier powerdown_notifier;
ac404095 82
9e047b98
MT
83 /* for legacy pci hotplug (compatible with qemu 1.6 and older) */
84 MemoryRegion io_pci;
ac404095 85 struct pci_status pci0_status;
668643b0 86 uint32_t pci0_hotplug_enable;
7faa8075 87 uint32_t pci0_slot_device_present;
459ae5ea 88
9e047b98
MT
89 /* for new pci hotplug (with PCI2PCI bridge support) */
90 AcpiPciHpState acpi_pci_hotplug;
91 bool use_acpi_pci_hotplug;
92
459ae5ea
GN
93 uint8_t disable_s3;
94 uint8_t disable_s4;
95 uint8_t s4_val;
b8622725 96
81cea5e7 97 AcpiCpuHotplug gpe_cpu;
b8622725 98 Notifier cpu_added_notifier;
93d89f63
IY
99} PIIX4PMState;
100
74e445f6
PC
101#define TYPE_PIIX4_PM "PIIX4_PM"
102
103#define PIIX4_PM(obj) \
104 OBJECT_CHECK(PIIX4PMState, (obj), TYPE_PIIX4_PM)
105
56e5b2a1
GH
106static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
107 PCIBus *bus, PIIX4PMState *s);
ac404095 108
93d89f63
IY
109#define ACPI_ENABLE 0xf1
110#define ACPI_DISABLE 0xf0
111
355bf2e5 112static void pm_tmr_timer(ACPIREGS *ar)
93d89f63 113{
355bf2e5 114 PIIX4PMState *s = container_of(ar, PIIX4PMState, ar);
06313503 115 acpi_update_sci(&s->ar, s->irq);
93d89f63
IY
116}
117
93d89f63
IY
118static void apm_ctrl_changed(uint32_t val, void *arg)
119{
120 PIIX4PMState *s = arg;
6a6b5580 121 PCIDevice *d = PCI_DEVICE(s);
93d89f63
IY
122
123 /* ACPI specs 3.0, 4.7.2.5 */
355bf2e5 124 acpi_pm1_cnt_update(&s->ar, val == ACPI_ENABLE, val == ACPI_DISABLE);
93d89f63 125
6a6b5580 126 if (d->config[0x5b] & (1 << 1)) {
93d89f63
IY
127 if (s->smi_irq) {
128 qemu_irq_raise(s->smi_irq);
129 }
130 }
131}
132
93d89f63
IY
133static void pm_io_space_update(PIIX4PMState *s)
134{
6a6b5580 135 PCIDevice *d = PCI_DEVICE(s);
93d89f63 136
277e9340
MT
137 s->io_base = le32_to_cpu(*(uint32_t *)(d->config + 0x40));
138 s->io_base &= 0xffc0;
93d89f63 139
af11110b 140 memory_region_transaction_begin();
6a6b5580 141 memory_region_set_enabled(&s->io, d->config[0x80] & 1);
277e9340 142 memory_region_set_address(&s->io, s->io_base);
af11110b 143 memory_region_transaction_commit();
93d89f63
IY
144}
145
24fe083d
GH
146static void smbus_io_space_update(PIIX4PMState *s)
147{
6a6b5580
AF
148 PCIDevice *d = PCI_DEVICE(s);
149
150 s->smb_io_base = le32_to_cpu(*(uint32_t *)(d->config + 0x90));
24fe083d
GH
151 s->smb_io_base &= 0xffc0;
152
153 memory_region_transaction_begin();
6a6b5580 154 memory_region_set_enabled(&s->smb.io, d->config[0xd2] & 1);
24fe083d
GH
155 memory_region_set_address(&s->smb.io, s->smb_io_base);
156 memory_region_transaction_commit();
93d89f63
IY
157}
158
159static void pm_write_config(PCIDevice *d,
160 uint32_t address, uint32_t val, int len)
161{
162 pci_default_write_config(d, address, val, len);
24fe083d
GH
163 if (range_covers_byte(address, len, 0x80) ||
164 ranges_overlap(address, len, 0x40, 4)) {
93d89f63 165 pm_io_space_update((PIIX4PMState *)d);
24fe083d
GH
166 }
167 if (range_covers_byte(address, len, 0xd2) ||
168 ranges_overlap(address, len, 0x90, 4)) {
169 smbus_io_space_update((PIIX4PMState *)d);
170 }
93d89f63
IY
171}
172
7faa8075
AW
173static void vmstate_pci_status_pre_save(void *opaque)
174{
175 struct pci_status *pci0_status = opaque;
176 PIIX4PMState *s = container_of(pci0_status, PIIX4PMState, pci0_status);
177
178 /* We no longer track up, so build a safe value for migrating
179 * to a version that still does... of course these might get lost
180 * by an old buggy implementation, but we try. */
181 pci0_status->up = s->pci0_slot_device_present & s->pci0_hotplug_enable;
182}
183
93d89f63
IY
184static int vmstate_acpi_post_load(void *opaque, int version_id)
185{
186 PIIX4PMState *s = opaque;
187
188 pm_io_space_update(s);
189 return 0;
190}
191
23910d3f
IY
192#define VMSTATE_GPE_ARRAY(_field, _state) \
193 { \
194 .name = (stringify(_field)), \
195 .version_id = 0, \
23910d3f
IY
196 .info = &vmstate_info_uint16, \
197 .size = sizeof(uint16_t), \
b0b873a0 198 .flags = VMS_SINGLE | VMS_POINTER, \
23910d3f
IY
199 .offset = vmstate_offset_pointer(_state, _field, uint8_t), \
200 }
201
4cf3e6f3
AW
202static const VMStateDescription vmstate_gpe = {
203 .name = "gpe",
204 .version_id = 1,
205 .minimum_version_id = 1,
206 .minimum_version_id_old = 1,
207 .fields = (VMStateField []) {
23910d3f
IY
208 VMSTATE_GPE_ARRAY(sts, ACPIGPE),
209 VMSTATE_GPE_ARRAY(en, ACPIGPE),
4cf3e6f3
AW
210 VMSTATE_END_OF_LIST()
211 }
212};
213
214static const VMStateDescription vmstate_pci_status = {
215 .name = "pci_status",
216 .version_id = 1,
217 .minimum_version_id = 1,
218 .minimum_version_id_old = 1,
7faa8075 219 .pre_save = vmstate_pci_status_pre_save,
4cf3e6f3
AW
220 .fields = (VMStateField []) {
221 VMSTATE_UINT32(up, struct pci_status),
222 VMSTATE_UINT32(down, struct pci_status),
223 VMSTATE_END_OF_LIST()
224 }
225};
226
b0b873a0
MT
227static int acpi_load_old(QEMUFile *f, void *opaque, int version_id)
228{
229 PIIX4PMState *s = opaque;
230 int ret, i;
231 uint16_t temp;
232
6a6b5580 233 ret = pci_device_load(PCI_DEVICE(s), f);
b0b873a0
MT
234 if (ret < 0) {
235 return ret;
236 }
237 qemu_get_be16s(f, &s->ar.pm1.evt.sts);
238 qemu_get_be16s(f, &s->ar.pm1.evt.en);
239 qemu_get_be16s(f, &s->ar.pm1.cnt.cnt);
240
ded67782 241 ret = vmstate_load_state(f, &vmstate_apm, &s->apm, 1);
b0b873a0
MT
242 if (ret) {
243 return ret;
244 }
245
40daca54 246 timer_get(f, s->ar.tmr.timer);
b0b873a0
MT
247 qemu_get_sbe64s(f, &s->ar.tmr.overflow_time);
248
249 qemu_get_be16s(f, (uint16_t *)s->ar.gpe.sts);
250 for (i = 0; i < 3; i++) {
251 qemu_get_be16s(f, &temp);
252 }
253
254 qemu_get_be16s(f, (uint16_t *)s->ar.gpe.en);
255 for (i = 0; i < 3; i++) {
256 qemu_get_be16s(f, &temp);
257 }
258
ded67782 259 ret = vmstate_load_state(f, &vmstate_pci_status, &s->pci0_status, 1);
b0b873a0
MT
260 return ret;
261}
262
9e047b98
MT
263static bool vmstate_test_use_acpi_pci_hotplug(void *opaque, int version_id)
264{
265 PIIX4PMState *s = opaque;
266 return s->use_acpi_pci_hotplug;
267}
268
269static bool vmstate_test_no_use_acpi_pci_hotplug(void *opaque, int version_id)
270{
271 PIIX4PMState *s = opaque;
272 return !s->use_acpi_pci_hotplug;
273}
274
b0b873a0
MT
275/* qemu-kvm 1.2 uses version 3 but advertised as 2
276 * To support incoming qemu-kvm 1.2 migration, change version_id
277 * and minimum_version_id to 2 below (which breaks migration from
278 * qemu 1.2).
279 *
280 */
93d89f63
IY
281static const VMStateDescription vmstate_acpi = {
282 .name = "piix4_pm",
b0b873a0
MT
283 .version_id = 3,
284 .minimum_version_id = 3,
93d89f63 285 .minimum_version_id_old = 1,
b0b873a0 286 .load_state_old = acpi_load_old,
93d89f63
IY
287 .post_load = vmstate_acpi_post_load,
288 .fields = (VMStateField []) {
6a6b5580 289 VMSTATE_PCI_DEVICE(parent_obj, PIIX4PMState),
355bf2e5
GH
290 VMSTATE_UINT16(ar.pm1.evt.sts, PIIX4PMState),
291 VMSTATE_UINT16(ar.pm1.evt.en, PIIX4PMState),
292 VMSTATE_UINT16(ar.pm1.cnt.cnt, PIIX4PMState),
93d89f63 293 VMSTATE_STRUCT(apm, PIIX4PMState, 0, vmstate_apm, APMState),
355bf2e5
GH
294 VMSTATE_TIMER(ar.tmr.timer, PIIX4PMState),
295 VMSTATE_INT64(ar.tmr.overflow_time, PIIX4PMState),
296 VMSTATE_STRUCT(ar.gpe, PIIX4PMState, 2, vmstate_gpe, ACPIGPE),
9e047b98
MT
297 VMSTATE_STRUCT_TEST(pci0_status, PIIX4PMState,
298 vmstate_test_no_use_acpi_pci_hotplug,
299 2, vmstate_pci_status,
300 struct pci_status),
301 VMSTATE_PCI_HOTPLUG(acpi_pci_hotplug, PIIX4PMState,
302 vmstate_test_use_acpi_pci_hotplug),
93d89f63
IY
303 VMSTATE_END_OF_LIST()
304 }
305};
306
7faa8075
AW
307static void acpi_piix_eject_slot(PIIX4PMState *s, unsigned slots)
308{
0866aca1 309 BusChild *kid, *next;
74e445f6 310 BusState *bus = qdev_get_parent_bus(DEVICE(s));
7faa8075 311 int slot = ffs(slots) - 1;
54bfa546 312 bool slot_free = true;
7faa8075
AW
313
314 /* Mark request as complete */
315 s->pci0_status.down &= ~(1U << slot);
316
0866aca1
AL
317 QTAILQ_FOREACH_SAFE(kid, &bus->children, sibling, next) {
318 DeviceState *qdev = kid->child;
7faa8075
AW
319 PCIDevice *dev = PCI_DEVICE(qdev);
320 PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
54bfa546
MT
321 if (PCI_SLOT(dev->devfn) == slot) {
322 if (pc->no_hotplug) {
323 slot_free = false;
324 } else {
02a5c4c9 325 object_unparent(OBJECT(qdev));
54bfa546 326 }
7faa8075
AW
327 }
328 }
54bfa546
MT
329 if (slot_free) {
330 s->pci0_slot_device_present &= ~(1U << slot);
331 }
7faa8075
AW
332}
333
668643b0
MT
334static void piix4_update_hotplug(PIIX4PMState *s)
335{
74e445f6 336 BusState *bus = qdev_get_parent_bus(DEVICE(s));
0866aca1 337 BusChild *kid, *next;
668643b0 338
7faa8075
AW
339 /* Execute any pending removes during reset */
340 while (s->pci0_status.down) {
341 acpi_piix_eject_slot(s, s->pci0_status.down);
342 }
343
668643b0 344 s->pci0_hotplug_enable = ~0;
7faa8075 345 s->pci0_slot_device_present = 0;
668643b0 346
0866aca1
AL
347 QTAILQ_FOREACH_SAFE(kid, &bus->children, sibling, next) {
348 DeviceState *qdev = kid->child;
40021f08
AL
349 PCIDevice *pdev = PCI_DEVICE(qdev);
350 PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pdev);
668643b0
MT
351 int slot = PCI_SLOT(pdev->devfn);
352
40021f08 353 if (pc->no_hotplug) {
7faa8075 354 s->pci0_hotplug_enable &= ~(1U << slot);
668643b0 355 }
7faa8075
AW
356
357 s->pci0_slot_device_present |= (1U << slot);
668643b0
MT
358 }
359}
360
93d89f63
IY
361static void piix4_reset(void *opaque)
362{
363 PIIX4PMState *s = opaque;
6a6b5580
AF
364 PCIDevice *d = PCI_DEVICE(s);
365 uint8_t *pci_conf = d->config;
93d89f63
IY
366
367 pci_conf[0x58] = 0;
368 pci_conf[0x59] = 0;
369 pci_conf[0x5a] = 0;
370 pci_conf[0x5b] = 0;
371
4d09d37c
GN
372 pci_conf[0x40] = 0x01; /* PM io base read only bit */
373 pci_conf[0x80] = 0;
374
93d89f63
IY
375 if (s->kvm_enabled) {
376 /* Mark SMM as already inited (until KVM supports SMM). */
377 pci_conf[0x5B] = 0x02;
378 }
c046e8c4 379 pm_io_space_update(s);
9e047b98
MT
380 if (s->use_acpi_pci_hotplug) {
381 acpi_pcihp_reset(&s->acpi_pci_hotplug);
382 } else {
383 piix4_update_hotplug(s);
384 }
93d89f63
IY
385}
386
d010f91c 387static void piix4_pm_powerdown_req(Notifier *n, void *opaque)
93d89f63 388{
d010f91c 389 PIIX4PMState *s = container_of(n, PIIX4PMState, powerdown_notifier);
93d89f63 390
355bf2e5
GH
391 assert(s != NULL);
392 acpi_pm1_evt_power_down(&s->ar);
93d89f63
IY
393}
394
9e047b98
MT
395static int piix4_acpi_pci_hotplug(DeviceState *qdev, PCIDevice *dev,
396 PCIHotplugState state)
397{
398 PIIX4PMState *s = PIIX4_PM(qdev);
399 int ret = acpi_pcihp_device_hotplug(&s->acpi_pci_hotplug, dev, state);
400 if (ret < 0) {
401 return ret;
402 }
403 s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
404
405 acpi_update_sci(&s->ar, s->irq);
406 return 0;
407}
408
409static void piix4_update_bus_hotplug(PCIBus *bus, void *opaque)
410{
411 PIIX4PMState *s = opaque;
412 pci_bus_hotplug(bus, piix4_acpi_pci_hotplug, DEVICE(s));
413}
414
9e8dd451 415static void piix4_pm_machine_ready(Notifier *n, void *opaque)
6141dbfe
PB
416{
417 PIIX4PMState *s = container_of(n, PIIX4PMState, machine_ready);
6a6b5580
AF
418 PCIDevice *d = PCI_DEVICE(s);
419 MemoryRegion *io_as = pci_address_space_io(d);
6141dbfe
PB
420 uint8_t *pci_conf;
421
6a6b5580 422 pci_conf = d->config;
b6f32962 423 pci_conf[0x5f] = 0x10 |
3ce10901 424 (memory_region_present(io_as, 0x378) ? 0x80 : 0);
6141dbfe 425 pci_conf[0x63] = 0x60;
3ce10901
PB
426 pci_conf[0x67] = (memory_region_present(io_as, 0x3f8) ? 0x08 : 0) |
427 (memory_region_present(io_as, 0x2f8) ? 0x90 : 0);
9e047b98
MT
428
429 if (s->use_acpi_pci_hotplug) {
430 pci_for_each_bus(d->bus, piix4_update_bus_hotplug, s);
431 }
6141dbfe
PB
432}
433
277e9340
MT
434static void piix4_pm_add_propeties(PIIX4PMState *s)
435{
436 static const uint8_t acpi_enable_cmd = ACPI_ENABLE;
437 static const uint8_t acpi_disable_cmd = ACPI_DISABLE;
438 static const uint32_t gpe0_blk = GPE_BASE;
439 static const uint32_t gpe0_blk_len = GPE_LEN;
440 static const uint16_t sci_int = 9;
441
442 object_property_add_uint8_ptr(OBJECT(s), ACPI_PM_PROP_ACPI_ENABLE_CMD,
443 &acpi_enable_cmd, NULL);
444 object_property_add_uint8_ptr(OBJECT(s), ACPI_PM_PROP_ACPI_DISABLE_CMD,
445 &acpi_disable_cmd, NULL);
446 object_property_add_uint32_ptr(OBJECT(s), ACPI_PM_PROP_GPE0_BLK,
447 &gpe0_blk, NULL);
448 object_property_add_uint32_ptr(OBJECT(s), ACPI_PM_PROP_GPE0_BLK_LEN,
449 &gpe0_blk_len, NULL);
450 object_property_add_uint16_ptr(OBJECT(s), ACPI_PM_PROP_SCI_INT,
451 &sci_int, NULL);
452 object_property_add_uint32_ptr(OBJECT(s), ACPI_PM_PROP_PM_IO_BASE,
453 &s->io_base, NULL);
454}
455
e8ec0571 456static int piix4_pm_initfn(PCIDevice *dev)
93d89f63 457{
74e445f6 458 PIIX4PMState *s = PIIX4_PM(dev);
93d89f63
IY
459 uint8_t *pci_conf;
460
6a6b5580 461 pci_conf = dev->config;
93d89f63
IY
462 pci_conf[0x06] = 0x80;
463 pci_conf[0x07] = 0x02;
93d89f63 464 pci_conf[0x09] = 0x00;
93d89f63
IY
465 pci_conf[0x3d] = 0x01; // interrupt pin 1
466
93d89f63 467 /* APM */
42d8a3cf 468 apm_init(dev, &s->apm, apm_ctrl_changed, s);
93d89f63 469
93d89f63
IY
470 if (s->kvm_enabled) {
471 /* Mark SMM as already inited to prevent SMM from running. KVM does not
472 * support SMM mode. */
473 pci_conf[0x5B] = 0x02;
474 }
475
476 /* XXX: which specification is used ? The i82731AB has different
477 mappings */
e8ec0571
IY
478 pci_conf[0x90] = s->smb_io_base | 1;
479 pci_conf[0x91] = s->smb_io_base >> 8;
93d89f63 480 pci_conf[0xd2] = 0x09;
74e445f6 481 pm_smbus_init(DEVICE(dev), &s->smb);
24fe083d 482 memory_region_set_enabled(&s->smb.io, pci_conf[0xd2] & 1);
56e5b2a1
GH
483 memory_region_add_subregion(pci_address_space_io(dev),
484 s->smb_io_base, &s->smb.io);
93d89f63 485
64bde0f3 486 memory_region_init(&s->io, OBJECT(s), "piix4-pm", 64);
af11110b 487 memory_region_set_enabled(&s->io, false);
56e5b2a1
GH
488 memory_region_add_subregion(pci_address_space_io(dev),
489 0, &s->io);
93d89f63 490
77d58b1e 491 acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io);
b5a7c024 492 acpi_pm1_evt_init(&s->ar, pm_tmr_timer, &s->io);
560e6396 493 acpi_pm1_cnt_init(&s->ar, &s->io, s->s4_val);
355bf2e5 494 acpi_gpe_init(&s->ar, GPE_LEN);
93d89f63 495
d010f91c
IM
496 s->powerdown_notifier.notify = piix4_pm_powerdown_req;
497 qemu_register_powerdown_notifier(&s->powerdown_notifier);
93d89f63 498
6141dbfe
PB
499 s->machine_ready.notify = piix4_pm_machine_ready;
500 qemu_add_machine_init_done_notifier(&s->machine_ready);
e8ec0571 501 qemu_register_reset(piix4_reset, s);
56e5b2a1
GH
502
503 piix4_acpi_system_hot_add_init(pci_address_space_io(dev), dev->bus, s);
e8ec0571 504
277e9340 505 piix4_pm_add_propeties(s);
e8ec0571
IY
506 return 0;
507}
508
277e9340
MT
509Object *piix4_pm_find(void)
510{
511 bool ambig;
512 Object *o = object_resolve_path_type("", TYPE_PIIX4_PM, &ambig);
513
514 if (ambig || !o) {
515 return NULL;
516 }
517 return o;
518}
519
a5c82852
AF
520I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
521 qemu_irq sci_irq, qemu_irq smi_irq,
522 int kvm_enabled, FWCfgState *fw_cfg)
e8ec0571 523{
74e445f6 524 DeviceState *dev;
e8ec0571
IY
525 PIIX4PMState *s;
526
74e445f6
PC
527 dev = DEVICE(pci_create(bus, devfn, TYPE_PIIX4_PM));
528 qdev_prop_set_uint32(dev, "smb_io_base", smb_io_base);
93d89f63 529
74e445f6 530 s = PIIX4_PM(dev);
93d89f63 531 s->irq = sci_irq;
93d89f63 532 s->smi_irq = smi_irq;
e8ec0571
IY
533 s->kvm_enabled = kvm_enabled;
534
74e445f6 535 qdev_init_nofail(dev);
93d89f63 536
459ae5ea
GN
537 if (fw_cfg) {
538 uint8_t suspend[6] = {128, 0, 0, 129, 128, 128};
539 suspend[3] = 1 | ((!s->disable_s3) << 7);
540 suspend[4] = s->s4_val | ((!s->disable_s4) << 7);
541
542 fw_cfg_add_file(fw_cfg, "etc/system-states", g_memdup(suspend, 6), 6);
543 }
544
93d89f63
IY
545 return s->smb.smbus;
546}
547
40021f08
AL
548static Property piix4_pm_properties[] = {
549 DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0),
f854ecc7
MT
550 DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 0),
551 DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_DISABLED, PIIX4PMState, disable_s4, 0),
552 DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_VAL, PIIX4PMState, s4_val, 2),
9e047b98
MT
553 DEFINE_PROP_BOOL("acpi-pci-hotplug-with-bridge-support", PIIX4PMState,
554 use_acpi_pci_hotplug, true),
40021f08
AL
555 DEFINE_PROP_END_OF_LIST(),
556};
557
558static void piix4_pm_class_init(ObjectClass *klass, void *data)
559{
39bffca2 560 DeviceClass *dc = DEVICE_CLASS(klass);
40021f08
AL
561 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
562
563 k->no_hotplug = 1;
564 k->init = piix4_pm_initfn;
565 k->config_write = pm_write_config;
566 k->vendor_id = PCI_VENDOR_ID_INTEL;
567 k->device_id = PCI_DEVICE_ID_INTEL_82371AB_3;
568 k->revision = 0x03;
569 k->class_id = PCI_CLASS_BRIDGE_OTHER;
39bffca2 570 dc->desc = "PM";
39bffca2
AL
571 dc->vmsd = &vmstate_acpi;
572 dc->props = piix4_pm_properties;
81aab2ff
MA
573 /*
574 * Reason: part of PIIX4 southbridge, needs to be wired up,
575 * e.g. by mips_malta_init()
576 */
577 dc->cannot_instantiate_with_device_add_yet = true;
40021f08
AL
578}
579
8c43a6f0 580static const TypeInfo piix4_pm_info = {
74e445f6 581 .name = TYPE_PIIX4_PM,
39bffca2
AL
582 .parent = TYPE_PCI_DEVICE,
583 .instance_size = sizeof(PIIX4PMState),
584 .class_init = piix4_pm_class_init,
e8ec0571
IY
585};
586
83f7d43a 587static void piix4_pm_register_types(void)
e8ec0571 588{
39bffca2 589 type_register_static(&piix4_pm_info);
e8ec0571
IY
590}
591
83f7d43a 592type_init(piix4_pm_register_types)
e8ec0571 593
b65b93f2 594static uint64_t gpe_readb(void *opaque, hwaddr addr, unsigned width)
93d89f63 595{
633aa0ac 596 PIIX4PMState *s = opaque;
355bf2e5 597 uint32_t val = acpi_gpe_ioport_readb(&s->ar, addr);
93d89f63 598
ba275adb 599 PIIX4_DPRINTF("gpe read %" HWADDR_PRIx " == %" PRIu32 "\n", addr, val);
93d89f63
IY
600 return val;
601}
602
b65b93f2
GH
603static void gpe_writeb(void *opaque, hwaddr addr, uint64_t val,
604 unsigned width)
93d89f63 605{
633aa0ac 606 PIIX4PMState *s = opaque;
633aa0ac 607
355bf2e5 608 acpi_gpe_ioport_writeb(&s->ar, addr, val);
06313503 609 acpi_update_sci(&s->ar, s->irq);
93d89f63 610
ba275adb 611 PIIX4_DPRINTF("gpe write %" HWADDR_PRIx " <== %" PRIu64 "\n", addr, val);
93d89f63
IY
612}
613
b65b93f2
GH
614static const MemoryRegionOps piix4_gpe_ops = {
615 .read = gpe_readb,
616 .write = gpe_writeb,
617 .valid.min_access_size = 1,
618 .valid.max_access_size = 4,
619 .impl.min_access_size = 1,
620 .impl.max_access_size = 1,
621 .endianness = DEVICE_LITTLE_ENDIAN,
622};
623
c3a29809 624static uint64_t pci_read(void *opaque, hwaddr addr, unsigned int size)
93d89f63 625{
ba737541 626 PIIX4PMState *s = opaque;
c3a29809
HP
627 uint32_t val = 0;
628
629 switch (addr) {
630 case PCI_UP_BASE - PCI_HOTPLUG_ADDR:
631 /* Manufacture an "up" value to cause a device check on any hotplug
632 * slot with a device. Extra device checks are harmless. */
633 val = s->pci0_slot_device_present & s->pci0_hotplug_enable;
ba275adb 634 PIIX4_DPRINTF("pci_up_read %" PRIu32 "\n", val);
c3a29809
HP
635 break;
636 case PCI_DOWN_BASE - PCI_HOTPLUG_ADDR:
637 val = s->pci0_status.down;
ba275adb 638 PIIX4_DPRINTF("pci_down_read %" PRIu32 "\n", val);
c3a29809
HP
639 break;
640 case PCI_EJ_BASE - PCI_HOTPLUG_ADDR:
641 /* No feature defined yet */
ba275adb 642 PIIX4_DPRINTF("pci_features_read %" PRIu32 "\n", val);
c3a29809
HP
643 break;
644 case PCI_RMV_BASE - PCI_HOTPLUG_ADDR:
645 val = s->pci0_hotplug_enable;
646 break;
647 default:
648 break;
649 }
ba737541 650
ba737541 651 return val;
93d89f63
IY
652}
653
c3a29809
HP
654static void pci_write(void *opaque, hwaddr addr, uint64_t data,
655 unsigned int size)
93d89f63 656{
c3a29809
HP
657 switch (addr) {
658 case PCI_EJ_BASE - PCI_HOTPLUG_ADDR:
659 acpi_piix_eject_slot(opaque, (uint32_t)data);
ba275adb 660 PIIX4_DPRINTF("pciej write %" HWADDR_PRIx " <== %" PRIu64 "\n",
c3a29809
HP
661 addr, data);
662 break;
663 default:
664 break;
665 }
668643b0
MT
666}
667
c177684c 668static const MemoryRegionOps piix4_pci_ops = {
c3a29809
HP
669 .read = pci_read,
670 .write = pci_write,
c177684c 671 .endianness = DEVICE_LITTLE_ENDIAN,
c3a29809
HP
672 .valid = {
673 .min_access_size = 4,
674 .max_access_size = 4,
675 },
c177684c
GH
676};
677
b8622725
IM
678static void piix4_cpu_added_req(Notifier *n, void *opaque)
679{
680 PIIX4PMState *s = container_of(n, PIIX4PMState, cpu_added_notifier);
681
81cea5e7
IM
682 assert(s != NULL);
683 AcpiCpuHotplug_add(&s->ar.gpe, &s->gpe_cpu, CPU(opaque));
684 acpi_update_sci(&s->ar, s->irq);
b8622725
IM
685}
686
4cff0a59
MT
687static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
688 PCIHotplugState state);
93d89f63 689
56e5b2a1
GH
690static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
691 PCIBus *bus, PIIX4PMState *s)
93d89f63 692{
64bde0f3
PB
693 memory_region_init_io(&s->io_gpe, OBJECT(s), &piix4_gpe_ops, s,
694 "acpi-gpe0", GPE_LEN);
56e5b2a1 695 memory_region_add_subregion(parent, GPE_BASE, &s->io_gpe);
ac404095 696
9e047b98
MT
697 if (s->use_acpi_pci_hotplug) {
698 acpi_pcihp_init(&s->acpi_pci_hotplug, bus, parent);
699 } else {
700 memory_region_init_io(&s->io_pci, OBJECT(s), &piix4_pci_ops, s,
701 "acpi-pci-hotplug", PCI_HOTPLUG_SIZE);
702 memory_region_add_subregion(parent, PCI_HOTPLUG_ADDR,
703 &s->io_pci);
704 pci_bus_hotplug(bus, piix4_device_hotplug, DEVICE(s));
705 }
b8622725 706
e4cf8ed0
IM
707 AcpiCpuHotplug_init(parent, OBJECT(s), &s->gpe_cpu,
708 PIIX4_CPU_HOTPLUG_IO_BASE);
b8622725
IM
709 s->cpu_added_notifier.notify = piix4_cpu_added_req;
710 qemu_register_cpu_added_notifier(&s->cpu_added_notifier);
93d89f63
IY
711}
712
ac404095 713static void enable_device(PIIX4PMState *s, int slot)
93d89f63 714{
355bf2e5 715 s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
7faa8075 716 s->pci0_slot_device_present |= (1U << slot);
93d89f63
IY
717}
718
ac404095 719static void disable_device(PIIX4PMState *s, int slot)
93d89f63 720{
355bf2e5 721 s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
7faa8075 722 s->pci0_status.down |= (1U << slot);
93d89f63
IY
723}
724
4cff0a59
MT
725static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
726 PCIHotplugState state)
93d89f63
IY
727{
728 int slot = PCI_SLOT(dev->devfn);
74e445f6 729 PIIX4PMState *s = PIIX4_PM(qdev);
93d89f63 730
4cff0a59
MT
731 /* Don't send event when device is enabled during qemu machine creation:
732 * it is present on boot, no hotplug event is necessary. We do send an
733 * event when the device is disabled later. */
734 if (state == PCI_COLDPLUG_ENABLED) {
7faa8075 735 s->pci0_slot_device_present |= (1U << slot);
5beb8ad5 736 return 0;
4cff0a59 737 }
5beb8ad5 738
4cff0a59 739 if (state == PCI_HOTPLUG_ENABLED) {
ac404095
IY
740 enable_device(s, slot);
741 } else {
742 disable_device(s, slot);
743 }
633aa0ac 744
06313503 745 acpi_update_sci(&s->ar, s->irq);
633aa0ac 746
93d89f63
IY
747 return 0;
748}