qemu

Форк
0
/
ich9.c 
561 строка · 18.8 Кб
1
/*
2
 * ACPI implementation
3
 *
4
 * Copyright (c) 2006 Fabrice Bellard
5
 * Copyright (c) 2009 Isaku Yamahata <yamahata at valinux co jp>
6
 *                    VA Linux Systems Japan K.K.
7
 * Copyright (C) 2012 Jason Baron <jbaron@redhat.com>
8
 *
9
 * This is based on acpi.c.
10
 *
11
 * This library is free software; you can redistribute it and/or
12
 * modify it under the terms of the GNU Lesser General Public
13
 * License version 2.1 as published by the Free Software Foundation.
14
 *
15
 * This library is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
 * Lesser General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Lesser General Public
21
 * License along with this library; if not, see <http://www.gnu.org/licenses/>
22
 *
23
 * Contributions after 2012-01-13 are licensed under the terms of the
24
 * GNU GPL, version 2 or (at your option) any later version.
25
 */
26

27
#include "qemu/osdep.h"
28
#include "qapi/error.h"
29
#include "qapi/visitor.h"
30
#include "hw/pci/pci.h"
31
#include "migration/vmstate.h"
32
#include "qemu/timer.h"
33
#include "hw/core/cpu.h"
34
#include "sysemu/reset.h"
35
#include "sysemu/runstate.h"
36
#include "hw/acpi/acpi.h"
37
#include "hw/acpi/ich9_tco.h"
38

39
#include "hw/southbridge/ich9.h"
40
#include "hw/mem/pc-dimm.h"
41
#include "hw/mem/nvdimm.h"
42

43
//#define DEBUG
44

45
#ifdef DEBUG
46
#define ICH9_DEBUG(fmt, ...) \
47
do { printf("%s "fmt, __func__, ## __VA_ARGS__); } while (0)
48
#else
49
#define ICH9_DEBUG(fmt, ...)    do { } while (0)
50
#endif
51

52
static void ich9_pm_update_sci_fn(ACPIREGS *regs)
53
{
54
    ICH9LPCPMRegs *pm = container_of(regs, ICH9LPCPMRegs, acpi_regs);
55
    acpi_update_sci(&pm->acpi_regs, pm->irq);
56
}
57

58
static uint64_t ich9_gpe_readb(void *opaque, hwaddr addr, unsigned width)
59
{
60
    ICH9LPCPMRegs *pm = opaque;
61
    return acpi_gpe_ioport_readb(&pm->acpi_regs, addr);
62
}
63

64
static void ich9_gpe_writeb(void *opaque, hwaddr addr, uint64_t val,
65
                            unsigned width)
66
{
67
    ICH9LPCPMRegs *pm = opaque;
68
    acpi_gpe_ioport_writeb(&pm->acpi_regs, addr, val);
69
    acpi_update_sci(&pm->acpi_regs, pm->irq);
70
}
71

72
static const MemoryRegionOps ich9_gpe_ops = {
73
    .read = ich9_gpe_readb,
74
    .write = ich9_gpe_writeb,
75
    .valid.min_access_size = 1,
76
    .valid.max_access_size = 4,
77
    .impl.min_access_size = 1,
78
    .impl.max_access_size = 1,
79
    .endianness = DEVICE_LITTLE_ENDIAN,
80
};
81

82
static uint64_t ich9_smi_readl(void *opaque, hwaddr addr, unsigned width)
83
{
84
    ICH9LPCPMRegs *pm = opaque;
85
    switch (addr) {
86
    case 0:
87
        return pm->smi_en;
88
    case 4:
89
        return pm->smi_sts;
90
    default:
91
        return 0;
92
    }
93
}
94

95
static void ich9_smi_writel(void *opaque, hwaddr addr, uint64_t val,
96
                            unsigned width)
97
{
98
    ICH9LPCPMRegs *pm = opaque;
99
    TCOIORegs *tr = &pm->tco_regs;
100
    uint64_t tco_en;
101

102
    switch (addr) {
103
    case 0:
104
        tco_en = pm->smi_en & ICH9_PMIO_SMI_EN_TCO_EN;
105
        /* once TCO_LOCK bit is set, TCO_EN bit cannot be overwritten */
106
        if (tr->tco.cnt1 & TCO_LOCK) {
107
            val = (val & ~ICH9_PMIO_SMI_EN_TCO_EN) | tco_en;
108
        }
109
        pm->smi_en &= ~pm->smi_en_wmask;
110
        pm->smi_en |= (val & pm->smi_en_wmask);
111
        break;
112
    }
113
}
114

115
static const MemoryRegionOps ich9_smi_ops = {
116
    .read = ich9_smi_readl,
117
    .write = ich9_smi_writel,
118
    .valid.min_access_size = 4,
119
    .valid.max_access_size = 4,
120
    .endianness = DEVICE_LITTLE_ENDIAN,
121
};
122

123
void ich9_pm_iospace_update(ICH9LPCPMRegs *pm, uint32_t pm_io_base)
124
{
125
    ICH9_DEBUG("to 0x%x\n", pm_io_base);
126

127
    assert((pm_io_base & ICH9_PMIO_MASK) == 0);
128

129
    pm->pm_io_base = pm_io_base;
130
    memory_region_transaction_begin();
131
    memory_region_set_enabled(&pm->io, pm->pm_io_base != 0);
132
    memory_region_set_address(&pm->io, pm->pm_io_base);
133
    memory_region_transaction_commit();
134
}
135

136
static int ich9_pm_post_load(void *opaque, int version_id)
137
{
138
    ICH9LPCPMRegs *pm = opaque;
139
    uint32_t pm_io_base = pm->pm_io_base;
140
    pm->pm_io_base = 0;
141
    ich9_pm_iospace_update(pm, pm_io_base);
142
    return 0;
143
}
144

145
#define VMSTATE_GPE_ARRAY(_field, _state)                            \
146
 {                                                                   \
147
     .name       = (stringify(_field)),                              \
148
     .version_id = 0,                                                \
149
     .num        = ICH9_PMIO_GPE0_LEN,                               \
150
     .info       = &vmstate_info_uint8,                              \
151
     .size       = sizeof(uint8_t),                                  \
152
     .flags      = VMS_ARRAY | VMS_POINTER,                          \
153
     .offset     = vmstate_offset_pointer(_state, _field, uint8_t),  \
154
 }
155

156
static const VMStateDescription vmstate_memhp_state = {
157
    .name = "ich9_pm/memhp",
158
    .version_id = 1,
159
    .minimum_version_id = 1,
160
    .fields = (const VMStateField[]) {
161
        VMSTATE_MEMORY_HOTPLUG(acpi_memory_hotplug, ICH9LPCPMRegs),
162
        VMSTATE_END_OF_LIST()
163
    }
164
};
165

166
static bool vmstate_test_use_tco(void *opaque)
167
{
168
    ICH9LPCPMRegs *s = opaque;
169
    return s->enable_tco;
170
}
171

172
static const VMStateDescription vmstate_tco_io_state = {
173
    .name = "ich9_pm/tco",
174
    .version_id = 1,
175
    .minimum_version_id = 1,
176
    .needed = vmstate_test_use_tco,
177
    .fields = (const VMStateField[]) {
178
        VMSTATE_STRUCT(tco_regs, ICH9LPCPMRegs, 1, vmstate_tco_io_sts,
179
                       TCOIORegs),
180
        VMSTATE_END_OF_LIST()
181
    }
182
};
183

184
static bool vmstate_test_use_cpuhp(void *opaque)
185
{
186
    ICH9LPCPMRegs *s = opaque;
187
    return !s->cpu_hotplug_legacy;
188
}
189

190
static int vmstate_cpuhp_pre_load(void *opaque)
191
{
192
    ICH9LPCPMRegs *s = opaque;
193
    Object *obj = OBJECT(s->gpe_cpu.device);
194
    object_property_set_bool(obj, "cpu-hotplug-legacy", false, &error_abort);
195
    return 0;
196
}
197

198
static const VMStateDescription vmstate_cpuhp_state = {
199
    .name = "ich9_pm/cpuhp",
200
    .version_id = 1,
201
    .minimum_version_id = 1,
202
    .needed = vmstate_test_use_cpuhp,
203
    .pre_load = vmstate_cpuhp_pre_load,
204
    .fields = (const VMStateField[]) {
205
        VMSTATE_CPU_HOTPLUG(cpuhp_state, ICH9LPCPMRegs),
206
        VMSTATE_END_OF_LIST()
207
    }
208
};
209

210
static bool vmstate_test_use_pcihp(void *opaque)
211
{
212
    ICH9LPCPMRegs *s = opaque;
213

214
    return s->acpi_pci_hotplug.use_acpi_hotplug_bridge;
215
}
216

217
static const VMStateDescription vmstate_pcihp_state = {
218
    .name = "ich9_pm/pcihp",
219
    .version_id = 1,
220
    .minimum_version_id = 1,
221
    .needed = vmstate_test_use_pcihp,
222
    .fields = (const VMStateField[]) {
223
        VMSTATE_PCI_HOTPLUG(acpi_pci_hotplug,
224
                            ICH9LPCPMRegs,
225
                            NULL, NULL),
226
        VMSTATE_END_OF_LIST()
227
    }
228
};
229

230
const VMStateDescription vmstate_ich9_pm = {
231
    .name = "ich9_pm",
232
    .version_id = 1,
233
    .minimum_version_id = 1,
234
    .post_load = ich9_pm_post_load,
235
    .fields = (const VMStateField[]) {
236
        VMSTATE_UINT16(acpi_regs.pm1.evt.sts, ICH9LPCPMRegs),
237
        VMSTATE_UINT16(acpi_regs.pm1.evt.en, ICH9LPCPMRegs),
238
        VMSTATE_UINT16(acpi_regs.pm1.cnt.cnt, ICH9LPCPMRegs),
239
        VMSTATE_TIMER_PTR(acpi_regs.tmr.timer, ICH9LPCPMRegs),
240
        VMSTATE_INT64(acpi_regs.tmr.overflow_time, ICH9LPCPMRegs),
241
        VMSTATE_GPE_ARRAY(acpi_regs.gpe.sts, ICH9LPCPMRegs),
242
        VMSTATE_GPE_ARRAY(acpi_regs.gpe.en, ICH9LPCPMRegs),
243
        VMSTATE_UINT32(smi_en, ICH9LPCPMRegs),
244
        VMSTATE_UINT32(smi_sts, ICH9LPCPMRegs),
245
        VMSTATE_END_OF_LIST()
246
    },
247
    .subsections = (const VMStateDescription * const []) {
248
        &vmstate_memhp_state,
249
        &vmstate_tco_io_state,
250
        &vmstate_cpuhp_state,
251
        &vmstate_pcihp_state,
252
        NULL
253
    }
254
};
255

256
static void pm_reset(void *opaque)
257
{
258
    ICH9LPCPMRegs *pm = opaque;
259
    ich9_pm_iospace_update(pm, 0);
260

261
    acpi_pm1_evt_reset(&pm->acpi_regs);
262
    acpi_pm1_cnt_reset(&pm->acpi_regs);
263
    acpi_pm_tmr_reset(&pm->acpi_regs);
264
    acpi_gpe_reset(&pm->acpi_regs);
265

266
    pm->smi_en = 0;
267
    if (!pm->smm_enabled) {
268
        /* Mark SMM as already inited to prevent SMM from running. */
269
        pm->smi_en |= ICH9_PMIO_SMI_EN_APMC_EN;
270
    }
271
    pm->smi_en_wmask = ~0;
272

273
    if (pm->acpi_pci_hotplug.use_acpi_hotplug_bridge) {
274
        acpi_pcihp_reset(&pm->acpi_pci_hotplug);
275
    }
276

277
    acpi_update_sci(&pm->acpi_regs, pm->irq);
278
}
279

280
static void pm_powerdown_req(Notifier *n, void *opaque)
281
{
282
    ICH9LPCPMRegs *pm = container_of(n, ICH9LPCPMRegs, powerdown_notifier);
283

284
    acpi_pm1_evt_power_down(&pm->acpi_regs);
285
}
286

287
void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, qemu_irq sci_irq)
288
{
289
    memory_region_init(&pm->io, OBJECT(lpc_pci), "ich9-pm", ICH9_PMIO_SIZE);
290
    memory_region_set_enabled(&pm->io, false);
291
    memory_region_add_subregion(pci_address_space_io(lpc_pci),
292
                                0, &pm->io);
293

294
    acpi_pm_tmr_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io);
295
    acpi_pm1_evt_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io);
296
    acpi_pm1_cnt_init(&pm->acpi_regs, &pm->io, pm->disable_s3, pm->disable_s4,
297
                      pm->s4_val, !pm->smm_compat && !pm->smm_enabled);
298

299
    acpi_gpe_init(&pm->acpi_regs, ICH9_PMIO_GPE0_LEN);
300
    memory_region_init_io(&pm->io_gpe, OBJECT(lpc_pci), &ich9_gpe_ops, pm,
301
                          "acpi-gpe0", ICH9_PMIO_GPE0_LEN);
302
    memory_region_add_subregion(&pm->io, ICH9_PMIO_GPE0_STS, &pm->io_gpe);
303

304
    memory_region_init_io(&pm->io_smi, OBJECT(lpc_pci), &ich9_smi_ops, pm,
305
                          "acpi-smi", 8);
306
    memory_region_add_subregion(&pm->io, ICH9_PMIO_SMI_EN, &pm->io_smi);
307

308
    if (pm->enable_tco) {
309
        acpi_pm_tco_init(&pm->tco_regs, &pm->io);
310
    }
311

312
    if (pm->acpi_pci_hotplug.use_acpi_hotplug_bridge) {
313
        acpi_pcihp_init(OBJECT(lpc_pci),
314
                        &pm->acpi_pci_hotplug,
315
                        pci_get_bus(lpc_pci),
316
                        pci_address_space_io(lpc_pci),
317
                        ACPI_PCIHP_ADDR_ICH9);
318

319
        qbus_set_hotplug_handler(BUS(pci_get_bus(lpc_pci)),
320
                                 OBJECT(lpc_pci));
321
    }
322

323
    pm->irq = sci_irq;
324
    qemu_register_reset(pm_reset, pm);
325
    pm->powerdown_notifier.notify = pm_powerdown_req;
326
    qemu_register_powerdown_notifier(&pm->powerdown_notifier);
327

328
    legacy_acpi_cpu_hotplug_init(pci_address_space_io(lpc_pci),
329
        OBJECT(lpc_pci), &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE);
330

331
    acpi_memory_hotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
332
                             &pm->acpi_memory_hotplug,
333
                             ACPI_MEMORY_HOTPLUG_BASE);
334
}
335

336
static void ich9_pm_get_gpe0_blk(Object *obj, Visitor *v, const char *name,
337
                                 void *opaque, Error **errp)
338
{
339
    ICH9LPCPMRegs *pm = opaque;
340
    uint32_t value = pm->pm_io_base + ICH9_PMIO_GPE0_STS;
341

342
    visit_type_uint32(v, name, &value, errp);
343
}
344

345
static bool ich9_pm_get_cpu_hotplug_legacy(Object *obj, Error **errp)
346
{
347
    ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
348

349
    return s->pm.cpu_hotplug_legacy;
350
}
351

352
static void ich9_pm_set_cpu_hotplug_legacy(Object *obj, bool value,
353
                                           Error **errp)
354
{
355
    ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
356

357
    assert(!value);
358
    if (s->pm.cpu_hotplug_legacy && value == false) {
359
        acpi_switch_to_modern_cphp(&s->pm.gpe_cpu, &s->pm.cpuhp_state,
360
                                   ICH9_CPU_HOTPLUG_IO_BASE);
361
    }
362
    s->pm.cpu_hotplug_legacy = value;
363
}
364

365
static bool ich9_pm_get_enable_tco(Object *obj, Error **errp)
366
{
367
    ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
368
    return s->pm.enable_tco;
369
}
370

371
static void ich9_pm_set_enable_tco(Object *obj, bool value, Error **errp)
372
{
373
    ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
374
    s->pm.enable_tco = value;
375
}
376

377
static bool ich9_pm_get_acpi_pci_hotplug(Object *obj, Error **errp)
378
{
379
    ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
380

381
    return s->pm.acpi_pci_hotplug.use_acpi_hotplug_bridge;
382
}
383

384
static void ich9_pm_set_acpi_pci_hotplug(Object *obj, bool value, Error **errp)
385
{
386
    ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
387

388
    s->pm.acpi_pci_hotplug.use_acpi_hotplug_bridge = value;
389
}
390

391
static bool ich9_pm_get_keep_pci_slot_hpc(Object *obj, Error **errp)
392
{
393
    ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
394

395
    return s->pm.keep_pci_slot_hpc;
396
}
397

398
static void ich9_pm_set_keep_pci_slot_hpc(Object *obj, bool value, Error **errp)
399
{
400
    ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
401

402
    s->pm.keep_pci_slot_hpc = value;
403
}
404

405
void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm)
406
{
407
    static const uint32_t gpe0_len = ICH9_PMIO_GPE0_LEN;
408
    pm->acpi_memory_hotplug.is_enabled = true;
409
    pm->cpu_hotplug_legacy = true;
410
    pm->disable_s3 = 0;
411
    pm->disable_s4 = 0;
412
    pm->s4_val = 2;
413
    pm->acpi_pci_hotplug.use_acpi_hotplug_bridge = true;
414
    pm->keep_pci_slot_hpc = true;
415
    pm->enable_tco = true;
416

417
    object_property_add_uint32_ptr(obj, ACPI_PM_PROP_PM_IO_BASE,
418
                                   &pm->pm_io_base, OBJ_PROP_FLAG_READ);
419
    object_property_add(obj, ACPI_PM_PROP_GPE0_BLK, "uint32",
420
                        ich9_pm_get_gpe0_blk,
421
                        NULL, NULL, pm);
422
    object_property_add_uint32_ptr(obj, ACPI_PM_PROP_GPE0_BLK_LEN,
423
                                   &gpe0_len, OBJ_PROP_FLAG_READ);
424
    object_property_add_bool(obj, "cpu-hotplug-legacy",
425
                             ich9_pm_get_cpu_hotplug_legacy,
426
                             ich9_pm_set_cpu_hotplug_legacy);
427
    object_property_add_uint8_ptr(obj, ACPI_PM_PROP_S3_DISABLED,
428
                                  &pm->disable_s3, OBJ_PROP_FLAG_READWRITE);
429
    object_property_add_uint8_ptr(obj, ACPI_PM_PROP_S4_DISABLED,
430
                                  &pm->disable_s4, OBJ_PROP_FLAG_READWRITE);
431
    object_property_add_uint8_ptr(obj, ACPI_PM_PROP_S4_VAL,
432
                                  &pm->s4_val, OBJ_PROP_FLAG_READWRITE);
433
    object_property_add_bool(obj, ACPI_PM_PROP_TCO_ENABLED,
434
                             ich9_pm_get_enable_tco,
435
                             ich9_pm_set_enable_tco);
436
    object_property_add_bool(obj, ACPI_PM_PROP_ACPI_PCIHP_BRIDGE,
437
                             ich9_pm_get_acpi_pci_hotplug,
438
                             ich9_pm_set_acpi_pci_hotplug);
439
    object_property_add_bool(obj, "x-keep-pci-slot-hpc",
440
                             ich9_pm_get_keep_pci_slot_hpc,
441
                             ich9_pm_set_keep_pci_slot_hpc);
442
}
443

444
void ich9_pm_device_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
445
                                Error **errp)
446
{
447
    ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
448

449
    if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
450
        acpi_pcihp_device_pre_plug_cb(hotplug_dev, dev, errp);
451
        return;
452
    }
453

454
    if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
455
        uint64_t negotiated = lpc->smi_negotiated_features;
456

457
        if (negotiated & BIT_ULL(ICH9_LPC_SMI_F_BROADCAST_BIT) &&
458
            !(negotiated & BIT_ULL(ICH9_LPC_SMI_F_CPU_HOTPLUG_BIT))) {
459
            error_setg(errp, "cpu hotplug with SMI wasn't enabled by firmware");
460
            error_append_hint(errp, "update machine type to newer than 5.1 "
461
                "and firmware that suppors CPU hotplug with SMM");
462
        }
463
    }
464
}
465

466
void ich9_pm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
467
                            Error **errp)
468
{
469
    ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
470

471
    if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
472
        if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {
473
            nvdimm_acpi_plug_cb(hotplug_dev, dev);
474
        } else {
475
            acpi_memory_plug_cb(hotplug_dev, &lpc->pm.acpi_memory_hotplug,
476
                                dev, errp);
477
        }
478
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
479
        if (lpc->pm.cpu_hotplug_legacy) {
480
            legacy_acpi_cpu_plug_cb(hotplug_dev, &lpc->pm.gpe_cpu, dev, errp);
481
        } else {
482
            acpi_cpu_plug_cb(hotplug_dev, &lpc->pm.cpuhp_state, dev, errp);
483
        }
484
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
485
        acpi_pcihp_device_plug_cb(hotplug_dev, &lpc->pm.acpi_pci_hotplug,
486
                                  dev, errp);
487
    } else {
488
        error_setg(errp, "acpi: device plug request for not supported device"
489
                   " type: %s", object_get_typename(OBJECT(dev)));
490
    }
491
}
492

493
void ich9_pm_device_unplug_request_cb(HotplugHandler *hotplug_dev,
494
                                      DeviceState *dev, Error **errp)
495
{
496
    ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
497

498
    if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
499
        acpi_memory_unplug_request_cb(hotplug_dev,
500
                                      &lpc->pm.acpi_memory_hotplug, dev,
501
                                      errp);
502
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU) &&
503
               !lpc->pm.cpu_hotplug_legacy) {
504
        uint64_t negotiated = lpc->smi_negotiated_features;
505

506
        if (negotiated & BIT_ULL(ICH9_LPC_SMI_F_BROADCAST_BIT) &&
507
            !(negotiated & BIT_ULL(ICH9_LPC_SMI_F_CPU_HOT_UNPLUG_BIT))) {
508
            error_setg(errp, "cpu hot-unplug with SMI wasn't enabled "
509
                             "by firmware");
510
            error_append_hint(errp, "update machine type to a version having "
511
                                    "x-smi-cpu-hotunplug=on and firmware that "
512
                                    "supports CPU hot-unplug with SMM");
513
            return;
514
        }
515

516
        acpi_cpu_unplug_request_cb(hotplug_dev, &lpc->pm.cpuhp_state,
517
                                   dev, errp);
518
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
519
        acpi_pcihp_device_unplug_request_cb(hotplug_dev,
520
                                            &lpc->pm.acpi_pci_hotplug,
521
                                            dev, errp);
522
    } else {
523
        error_setg(errp, "acpi: device unplug request for not supported device"
524
                   " type: %s", object_get_typename(OBJECT(dev)));
525
    }
526
}
527

528
void ich9_pm_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
529
                              Error **errp)
530
{
531
    ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
532

533
    if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
534
        acpi_memory_unplug_cb(&lpc->pm.acpi_memory_hotplug, dev, errp);
535
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU) &&
536
               !lpc->pm.cpu_hotplug_legacy) {
537
        acpi_cpu_unplug_cb(&lpc->pm.cpuhp_state, dev, errp);
538
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
539
        acpi_pcihp_device_unplug_cb(hotplug_dev, &lpc->pm.acpi_pci_hotplug,
540
                                    dev, errp);
541
    } else {
542
        error_setg(errp, "acpi: device unplug for not supported device"
543
                   " type: %s", object_get_typename(OBJECT(dev)));
544
    }
545
}
546

547
bool ich9_pm_is_hotpluggable_bus(HotplugHandler *hotplug_dev, BusState *bus)
548
{
549
    ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
550
    return acpi_pcihp_is_hotpluggbale_bus(&lpc->pm.acpi_pci_hotplug, bus);
551
}
552

553
void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list)
554
{
555
    ICH9LPCState *s = ICH9_LPC_DEVICE(adev);
556

557
    acpi_memory_ospm_status(&s->pm.acpi_memory_hotplug, list);
558
    if (!s->pm.cpu_hotplug_legacy) {
559
        acpi_cpu_ospm_status(&s->pm.cpuhp_state, list);
560
    }
561
}
562

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.