xref: /openbmc/qemu/hw/acpi/pcihp.c (revision b9dc4e04c807ad3860a9ba8773b3b0e7057c31aa)
1 /*
2  * QEMU<->ACPI BIOS PCI hotplug interface
3  *
4  * QEMU supports PCI hotplug via ACPI. This module
5  * implements the interface between QEMU and the ACPI BIOS.
6  * Interface specification - see docs/specs/acpi_pci_hotplug.rst
7  *
8  * Copyright (c) 2013, Red Hat Inc, Michael S. Tsirkin (mst@redhat.com)
9  * Copyright (c) 2006 Fabrice Bellard
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 "hw/acpi/pcihp.h"
29 #include "hw/acpi/aml-build.h"
30 #include "hw/acpi/acpi_aml_interface.h"
31 #include "hw/pci-host/i440fx.h"
32 #include "hw/pci/pci.h"
33 #include "hw/pci/pci_bridge.h"
34 #include "hw/pci/pci_host.h"
35 #include "hw/pci/pcie_port.h"
36 #include "hw/pci-bridge/xio3130_downstream.h"
37 #include "hw/i386/acpi-build.h"
38 #include "hw/acpi/acpi.h"
39 #include "hw/pci/pci_bus.h"
40 #include "migration/vmstate.h"
41 #include "qapi/error.h"
42 #include "qom/qom-qobject.h"
43 #include "qobject/qnum.h"
44 #include "trace.h"
45 
46 #define ACPI_PCIHP_SIZE 0x0018
47 #define PCI_UP_BASE 0x0000
48 #define PCI_DOWN_BASE 0x0004
49 #define PCI_EJ_BASE 0x0008
50 #define PCI_RMV_BASE 0x000c
51 #define PCI_SEL_BASE 0x0010
52 #define PCI_AIDX_BASE 0x0014
53 
54 typedef struct AcpiPciHpFind {
55     int bsel;
56     PCIBus *bus;
57 } AcpiPciHpFind;
58 
59 static int acpi_pcihp_get_bsel(PCIBus *bus)
60 {
61     Error *local_err = NULL;
62     uint64_t bsel = object_property_get_uint(OBJECT(bus), ACPI_PCIHP_PROP_BSEL,
63                                              &local_err);
64 
65     if (local_err || bsel >= ACPI_PCIHP_MAX_HOTPLUG_BUS) {
66         if (local_err) {
67             error_free(local_err);
68         }
69         return -1;
70     } else {
71         return bsel;
72     }
73 }
74 
75 typedef struct {
76     unsigned bsel_alloc;
77     bool has_bridge_hotplug;
78 } BSELInfo;
79 
80 /* Assign BSEL property only to buses that support hotplug. */
81 static void *acpi_set_bsel(PCIBus *bus, void *opaque)
82 {
83     BSELInfo *info = opaque;
84     unsigned *bus_bsel;
85     DeviceState *br = bus->qbus.parent;
86     bool is_bridge = IS_PCI_BRIDGE(br);
87 
88     /* hotplugged bridges can't be described in ACPI ignore them */
89     if (qbus_is_hotpluggable(BUS(bus))) {
90         if (!is_bridge || (!br->hotplugged && info->has_bridge_hotplug)) {
91             bus_bsel = g_malloc(sizeof *bus_bsel);
92 
93             *bus_bsel = info->bsel_alloc++;
94             object_property_add_uint32_ptr(OBJECT(bus), ACPI_PCIHP_PROP_BSEL,
95                                            bus_bsel, OBJ_PROP_FLAG_READ);
96         }
97     }
98 
99     return info;
100 }
101 
102 static void acpi_set_pci_info(AcpiPciHpState *s)
103 {
104     static bool bsel_is_set;
105     bool has_bridge_hotplug = s->use_acpi_hotplug_bridge;
106     PCIBus *bus;
107     BSELInfo info = { .bsel_alloc = ACPI_PCIHP_BSEL_DEFAULT,
108                       .has_bridge_hotplug = has_bridge_hotplug };
109 
110     if (bsel_is_set) {
111         return;
112     }
113     bsel_is_set = true;
114 
115 
116     bus = s->root;
117     if (bus) {
118         /* Scan all PCI buses. Set property to enable acpi based hotplug. */
119         pci_for_each_bus_depth_first(bus, acpi_set_bsel, NULL, &info);
120     }
121 }
122 
123 static void acpi_pcihp_test_hotplug_bus(PCIBus *bus, void *opaque)
124 {
125     AcpiPciHpFind *find = opaque;
126     if (find->bsel == acpi_pcihp_get_bsel(bus)) {
127         find->bus = bus;
128     }
129 }
130 
131 static PCIBus *acpi_pcihp_find_hotplug_bus(AcpiPciHpState *s, int bsel)
132 {
133     AcpiPciHpFind find = { .bsel = bsel, .bus = NULL };
134 
135     if (bsel < 0) {
136         return NULL;
137     }
138 
139     pci_for_each_bus(s->root, acpi_pcihp_test_hotplug_bus, &find);
140 
141     /* Make bsel 0 eject root bus if bsel property is not set,
142      * for compatibility with non acpi setups.
143      * TODO: really needed?
144      */
145     if (!bsel && !find.bus) {
146         find.bus = s->root;
147     }
148 
149     /*
150      * Check if find.bus is actually hotpluggable. If bsel is set to
151      * NULL for example on the root bus in order to make it
152      * non-hotpluggable, find.bus will match the root bus when bsel
153      * is 0. See acpi_pcihp_test_hotplug_bus() above. Since the
154      * bus is not hotpluggable however, we should not select the bus.
155      * Instead, we should set find.bus to NULL in that case. In the check
156      * below, we generalize this case for all buses, not just the root bus.
157      * The callers of this function check for a null return value and
158      * handle them appropriately.
159      */
160     if (find.bus && !qbus_is_hotpluggable(BUS(find.bus))) {
161         find.bus = NULL;
162     }
163     return find.bus;
164 }
165 
166 static bool acpi_pcihp_pc_no_hotplug(AcpiPciHpState *s, PCIDevice *dev)
167 {
168     DeviceClass *dc = DEVICE_GET_CLASS(dev);
169     /*
170      * ACPI doesn't allow hotplug of bridge devices.  Don't allow
171      * hot-unplug of bridge devices unless they were added by hotplug
172      * (and so, not described by acpi).
173      *
174      * Don't allow hot-unplug of SR-IOV Virtual Functions, as they
175      * will be removed implicitly, when Physical Function is unplugged.
176      */
177     return (IS_PCI_BRIDGE(dev) && !dev->qdev.hotplugged) || !dc->hotpluggable ||
178            pci_is_vf(dev);
179 }
180 
181 static void acpi_pcihp_eject_slot(AcpiPciHpState *s, unsigned bsel, unsigned slots)
182 {
183     HotplugHandler *hotplug_ctrl;
184     BusChild *kid, *next;
185     int slot = ctz32(slots);
186     PCIBus *bus = acpi_pcihp_find_hotplug_bus(s, bsel);
187 
188     trace_acpi_pci_eject_slot(bsel, slot);
189 
190     if (!bus || slot > 31) {
191         return;
192     }
193 
194     /* Mark request as complete */
195     s->acpi_pcihp_pci_status[bsel].down &= ~(1U << slot);
196     s->acpi_pcihp_pci_status[bsel].up &= ~(1U << slot);
197 
198     QTAILQ_FOREACH_SAFE(kid, &bus->qbus.children, sibling, next) {
199         DeviceState *qdev = kid->child;
200         PCIDevice *dev = PCI_DEVICE(qdev);
201         if (PCI_SLOT(dev->devfn) == slot) {
202             if (!acpi_pcihp_pc_no_hotplug(s, dev)) {
203                 /*
204                  * partially_hotplugged is used by virtio-net failover:
205                  * failover has asked the guest OS to unplug the device
206                  * but we need to keep some references to the device
207                  * to be able to plug it back in case of failure so
208                  * we don't execute hotplug_handler_unplug().
209                  */
210                 if (dev->partially_hotplugged) {
211                     /*
212                      * pending_deleted_event is set to true when
213                      * virtio-net failover asks to unplug the device,
214                      * and set to false here when the operation is done
215                      * This is used by the migration loop to detect the
216                      * end of the operation and really start the migration.
217                      */
218                     qdev->pending_deleted_event = false;
219                 } else {
220                     hotplug_ctrl = qdev_get_hotplug_handler(qdev);
221                     hotplug_handler_unplug(hotplug_ctrl, qdev, &error_abort);
222                     object_unparent(OBJECT(qdev));
223                 }
224             }
225         }
226     }
227 }
228 
229 static void acpi_pcihp_update_hotplug_bus(AcpiPciHpState *s, int bsel)
230 {
231     BusChild *kid, *next;
232     PCIBus *bus = acpi_pcihp_find_hotplug_bus(s, bsel);
233 
234     /* Execute any pending removes during reset */
235     while (s->acpi_pcihp_pci_status[bsel].down) {
236         acpi_pcihp_eject_slot(s, bsel, s->acpi_pcihp_pci_status[bsel].down);
237     }
238 
239     s->acpi_pcihp_pci_status[bsel].hotplug_enable = ~0;
240 
241     if (!bus) {
242         return;
243     }
244     QTAILQ_FOREACH_SAFE(kid, &bus->qbus.children, sibling, next) {
245         DeviceState *qdev = kid->child;
246         PCIDevice *pdev = PCI_DEVICE(qdev);
247         int slot = PCI_SLOT(pdev->devfn);
248 
249         if (acpi_pcihp_pc_no_hotplug(s, pdev)) {
250             s->acpi_pcihp_pci_status[bsel].hotplug_enable &= ~(1U << slot);
251         }
252     }
253 }
254 
255 static void acpi_pcihp_update(AcpiPciHpState *s)
256 {
257     int i;
258 
259     for (i = 0; i < ACPI_PCIHP_MAX_HOTPLUG_BUS; ++i) {
260         acpi_pcihp_update_hotplug_bus(s, i);
261     }
262 }
263 
264 void acpi_pcihp_reset(AcpiPciHpState *s)
265 {
266     acpi_set_pci_info(s);
267     acpi_pcihp_update(s);
268 }
269 
270 void acpi_pcihp_device_pre_plug_cb(HotplugHandler *hotplug_dev,
271                                    DeviceState *dev, Error **errp)
272 {
273     PCIDevice *pdev = PCI_DEVICE(dev);
274 
275     /* Only hotplugged devices need the hotplug capability. */
276     if (dev->hotplugged &&
277         acpi_pcihp_get_bsel(pci_get_bus(pdev)) < 0) {
278         error_setg(errp, "Unsupported bus. Bus doesn't have property '"
279                    ACPI_PCIHP_PROP_BSEL "' set");
280         return;
281     }
282 }
283 
284 void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
285                                DeviceState *dev, Error **errp)
286 {
287     PCIDevice *pdev = PCI_DEVICE(dev);
288     int slot = PCI_SLOT(pdev->devfn);
289     PCIDevice *bridge;
290     PCIBus *bus;
291     int bsel;
292 
293     /* Don't send event when device is enabled during qemu machine creation:
294      * it is present on boot, no hotplug event is necessary. We do send an
295      * event when the device is disabled later. */
296     if (!dev->hotplugged) {
297         /*
298          * Overwrite the default hotplug handler with the ACPI PCI one
299          * for cold plugged bridges only.
300          */
301         if (s->use_acpi_hotplug_bridge &&
302             object_dynamic_cast(OBJECT(dev), TYPE_PCI_BRIDGE)) {
303             PCIBus *sec = pci_bridge_get_sec_bus(PCI_BRIDGE(pdev));
304 
305             qbus_set_hotplug_handler(BUS(sec), OBJECT(hotplug_dev));
306             /* We don't have to overwrite any other hotplug handler yet */
307             assert(QLIST_EMPTY(&sec->child));
308         }
309 
310         return;
311     }
312 
313     bus = pci_get_bus(pdev);
314     bridge = pci_bridge_get_device(bus);
315     if (object_dynamic_cast(OBJECT(bridge), TYPE_PCIE_ROOT_PORT) ||
316         object_dynamic_cast(OBJECT(bridge), TYPE_XIO3130_DOWNSTREAM)) {
317         pcie_cap_slot_enable_power(bridge);
318     }
319 
320     bsel = acpi_pcihp_get_bsel(bus);
321     g_assert(bsel >= 0);
322     s->acpi_pcihp_pci_status[bsel].up |= (1U << slot);
323     acpi_send_event(DEVICE(hotplug_dev), ACPI_PCI_HOTPLUG_STATUS);
324 }
325 
326 void acpi_pcihp_device_unplug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
327                                  DeviceState *dev, Error **errp)
328 {
329     PCIDevice *pdev = PCI_DEVICE(dev);
330 
331     trace_acpi_pci_unplug(PCI_SLOT(pdev->devfn),
332                           acpi_pcihp_get_bsel(pci_get_bus(pdev)));
333 
334     qdev_unrealize(dev);
335 }
336 
337 void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev,
338                                          AcpiPciHpState *s, DeviceState *dev,
339                                          Error **errp)
340 {
341     PCIDevice *pdev = PCI_DEVICE(dev);
342     int slot = PCI_SLOT(pdev->devfn);
343     int bsel = acpi_pcihp_get_bsel(pci_get_bus(pdev));
344 
345     trace_acpi_pci_unplug_request(bsel, slot);
346 
347     if (bsel < 0) {
348         error_setg(errp, "Unsupported bus. Bus doesn't have property '"
349                    ACPI_PCIHP_PROP_BSEL "' set");
350         return;
351     }
352 
353     /*
354      * pending_deleted_event is used by virtio-net failover to detect the
355      * end of the unplug operation, the flag is set to false in
356      * acpi_pcihp_eject_slot() when the operation is completed.
357      */
358     pdev->qdev.pending_deleted_event = true;
359     /* if unplug was requested before OSPM is initialized,
360      * linux kernel will clear GPE0.sts[] bits during boot, which effectively
361      * hides unplug event. And than followup qmp_device_del() calls remain
362      * blocked by above flag permanently.
363      * Unblock qmp_device_del() by setting expire limit, so user can
364      * repeat unplug request later when OSPM has been booted.
365      */
366     pdev->qdev.pending_deleted_expires_ms =
367         qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL); /* 1 msec */
368 
369     s->acpi_pcihp_pci_status[bsel].down |= (1U << slot);
370     acpi_send_event(DEVICE(hotplug_dev), ACPI_PCI_HOTPLUG_STATUS);
371 }
372 
373 bool acpi_pcihp_is_hotpluggable_bus(AcpiPciHpState *s, BusState *bus)
374 {
375     Object *o = OBJECT(bus->parent);
376 
377     if (s->use_acpi_hotplug_bridge &&
378         object_dynamic_cast(o, TYPE_PCI_BRIDGE)) {
379         if (object_dynamic_cast(o, TYPE_PCIE_SLOT) && !PCIE_SLOT(o)->hotplug) {
380             return false;
381         }
382         return true;
383     }
384 
385     if (s->use_acpi_root_pci_hotplug) {
386         return true;
387     }
388     return false;
389 }
390 
391 static uint64_t pci_read(void *opaque, hwaddr addr, unsigned int size)
392 {
393     AcpiPciHpState *s = opaque;
394     uint32_t val = 0;
395     int bsel = s->hotplug_select;
396 
397     if (bsel < 0 || bsel >= ACPI_PCIHP_MAX_HOTPLUG_BUS) {
398         return 0;
399     }
400 
401     switch (addr) {
402     case PCI_UP_BASE:
403         val = s->acpi_pcihp_pci_status[bsel].up;
404         if (s->use_acpi_hotplug_bridge) {
405             s->acpi_pcihp_pci_status[bsel].up = 0;
406         }
407         trace_acpi_pci_up_read(val);
408         break;
409     case PCI_DOWN_BASE:
410         val = s->acpi_pcihp_pci_status[bsel].down;
411         trace_acpi_pci_down_read(val);
412         break;
413     case PCI_EJ_BASE:
414         trace_acpi_pci_features_read(val);
415         break;
416     case PCI_RMV_BASE:
417         val = s->acpi_pcihp_pci_status[bsel].hotplug_enable;
418         trace_acpi_pci_rmv_read(val);
419         break;
420     case PCI_SEL_BASE:
421         val = s->hotplug_select;
422         trace_acpi_pci_sel_read(val);
423         break;
424     case PCI_AIDX_BASE:
425         val = s->acpi_index;
426         s->acpi_index = 0;
427         trace_acpi_pci_acpi_index_read(val);
428         break;
429     default:
430         break;
431     }
432 
433     return val;
434 }
435 
436 static void pci_write(void *opaque, hwaddr addr, uint64_t data,
437                       unsigned int size)
438 {
439     int slot;
440     PCIBus *bus;
441     BusChild *kid, *next;
442     AcpiPciHpState *s = opaque;
443 
444     s->acpi_index = 0;
445     switch (addr) {
446     case PCI_AIDX_BASE:
447         /*
448          * fetch acpi-index for specified slot so that follow up read from
449          * PCI_AIDX_BASE can return it to guest
450          */
451         slot = ctz32(data);
452 
453         if (s->hotplug_select >= ACPI_PCIHP_MAX_HOTPLUG_BUS) {
454             break;
455         }
456 
457         bus = acpi_pcihp_find_hotplug_bus(s, s->hotplug_select);
458         if (!bus) {
459             break;
460         }
461         QTAILQ_FOREACH_SAFE(kid, &bus->qbus.children, sibling, next) {
462             Object *o = OBJECT(kid->child);
463             PCIDevice *dev = PCI_DEVICE(o);
464             if (PCI_SLOT(dev->devfn) == slot) {
465                 s->acpi_index = object_property_get_uint(o, "acpi-index", NULL);
466                 break;
467             }
468         }
469         trace_acpi_pci_acpi_index_write(s->hotplug_select, slot, s->acpi_index);
470         break;
471     case PCI_EJ_BASE:
472         if (s->hotplug_select >= ACPI_PCIHP_MAX_HOTPLUG_BUS) {
473             break;
474         }
475         acpi_pcihp_eject_slot(s, s->hotplug_select, data);
476         trace_acpi_pci_ej_write(addr, data);
477         break;
478     case PCI_SEL_BASE:
479         s->hotplug_select = s->use_acpi_hotplug_bridge ? data :
480             ACPI_PCIHP_BSEL_DEFAULT;
481         trace_acpi_pci_sel_write(addr, data);
482     default:
483         break;
484     }
485 }
486 
487 static const MemoryRegionOps acpi_pcihp_io_ops = {
488     .read = pci_read,
489     .write = pci_write,
490     .endianness = DEVICE_LITTLE_ENDIAN,
491     .valid = {
492         .min_access_size = 4,
493         .max_access_size = 4,
494     },
495 };
496 
497 void acpi_pcihp_init(Object *owner, AcpiPciHpState *s, PCIBus *root_bus,
498                      MemoryRegion *io, uint16_t io_base)
499 {
500     s->io_len = ACPI_PCIHP_SIZE;
501     s->io_base = io_base;
502 
503     s->root = root_bus;
504 
505     memory_region_init_io(&s->io, owner, &acpi_pcihp_io_ops, s,
506                           "acpi-pci-hotplug", s->io_len);
507     memory_region_add_subregion(io, s->io_base, &s->io);
508 
509     object_property_add_uint16_ptr(owner, ACPI_PCIHP_IO_BASE_PROP, &s->io_base,
510                                    OBJ_PROP_FLAG_READ);
511     object_property_add_uint16_ptr(owner, ACPI_PCIHP_IO_LEN_PROP, &s->io_len,
512                                    OBJ_PROP_FLAG_READ);
513 }
514 
515 void build_append_pci_dsm_func0_common(Aml *ctx, Aml *retvar)
516 {
517     Aml *UUID, *ifctx1;
518     uint8_t byte_list[1] = { 0 }; /* nothing supported yet */
519 
520     aml_append(ctx, aml_store(aml_buffer(1, byte_list), retvar));
521     /*
522      * PCI Firmware Specification 3.1
523      * 4.6.  _DSM Definitions for PCI
524      */
525     UUID = aml_touuid("E5C937D0-3553-4D7A-9117-EA4D19C3434D");
526     ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(0), UUID)));
527     {
528         /* call is for unsupported UUID, bail out */
529         aml_append(ifctx1, aml_return(retvar));
530     }
531     aml_append(ctx, ifctx1);
532 
533     ifctx1 = aml_if(aml_lless(aml_arg(1), aml_int(2)));
534     {
535         /* call is for unsupported REV, bail out */
536         aml_append(ifctx1, aml_return(retvar));
537     }
538     aml_append(ctx, ifctx1);
539 }
540 
541 static Aml *aml_pci_pdsm(void)
542 {
543     Aml *method, *ifctx, *ifctx1;
544     Aml *ret = aml_local(0);
545     Aml *caps = aml_local(1);
546     Aml *acpi_index = aml_local(2);
547     Aml *zero = aml_int(0);
548     Aml *one = aml_int(1);
549     Aml *not_supp = aml_int(0xFFFFFFFF);
550     Aml *func = aml_arg(2);
551     Aml *params = aml_arg(4);
552     Aml *bnum = aml_derefof(aml_index(params, aml_int(0)));
553     Aml *sunum = aml_derefof(aml_index(params, aml_int(1)));
554 
555     method = aml_method("PDSM", 5, AML_SERIALIZED);
556 
557     /* get supported functions */
558     ifctx = aml_if(aml_equal(func, zero));
559     {
560         build_append_pci_dsm_func0_common(ifctx, ret);
561 
562         aml_append(ifctx, aml_store(zero, caps));
563         aml_append(ifctx,
564             aml_store(aml_call2("AIDX", bnum, sunum), acpi_index));
565         /*
566          * advertise function 7 if device has acpi-index
567          * acpi_index values:
568          *            0: not present (default value)
569          *     FFFFFFFF: not supported (old QEMU without PIDX reg)
570          *        other: device's acpi-index
571          */
572         ifctx1 = aml_if(aml_lnot(
573                      aml_or(aml_equal(acpi_index, zero),
574                             aml_equal(acpi_index, not_supp), NULL)
575                  ));
576         {
577             /* have supported functions */
578             aml_append(ifctx1, aml_or(caps, one, caps));
579             /* support for function 7 */
580             aml_append(ifctx1,
581                 aml_or(caps, aml_shiftleft(one, aml_int(7)), caps));
582         }
583         aml_append(ifctx, ifctx1);
584 
585         aml_append(ifctx, aml_store(caps, aml_index(ret, zero)));
586         aml_append(ifctx, aml_return(ret));
587     }
588     aml_append(method, ifctx);
589 
590     /* handle specific functions requests */
591     /*
592      * PCI Firmware Specification 3.1
593      * 4.6.7. _DSM for Naming a PCI or PCI Express Device Under
594      *        Operating Systems
595      */
596     ifctx = aml_if(aml_equal(func, aml_int(7)));
597     {
598        Aml *pkg = aml_package(2);
599 
600        aml_append(ifctx, aml_store(aml_call2("AIDX", bnum, sunum), acpi_index));
601        aml_append(ifctx, aml_store(pkg, ret));
602        /*
603         * Windows calls func=7 without checking if it's available,
604         * as workaround Microsoft has suggested to return invalid for func7
605         * Package, so return 2 elements package but only initialize elements
606         * when acpi_index is supported and leave them uninitialized, which
607         * leads elements to being Uninitialized ObjectType and should trip
608         * Windows into discarding result as an unexpected and prevent setting
609         * bogus 'PCI Label' on the device.
610         */
611        ifctx1 = aml_if(aml_lnot(aml_lor(
612                     aml_equal(acpi_index, zero), aml_equal(acpi_index, not_supp)
613                 )));
614        {
615            aml_append(ifctx1, aml_store(acpi_index, aml_index(ret, zero)));
616            /*
617             * optional, if not impl. should return null string
618             */
619            aml_append(ifctx1, aml_store(aml_string("%s", ""),
620                                         aml_index(ret, one)));
621        }
622        aml_append(ifctx, ifctx1);
623 
624        aml_append(ifctx, aml_return(ret));
625     }
626 
627     aml_append(method, ifctx);
628     return method;
629 }
630 
631 void build_acpi_pci_hotplug(Aml *table, AmlRegionSpace rs, uint64_t pcihp_addr)
632 {
633     Aml *scope;
634     Aml *field;
635     Aml *method;
636 
637     scope =  aml_scope("_SB.PCI0");
638 
639     aml_append(scope,
640         aml_operation_region("PCST", rs, aml_int(pcihp_addr), 0x08));
641     field = aml_field("PCST", AML_DWORD_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS);
642     aml_append(field, aml_named_field("PCIU", 32));
643     aml_append(field, aml_named_field("PCID", 32));
644     aml_append(scope, field);
645 
646     aml_append(scope,
647         aml_operation_region("SEJ", rs,
648                              aml_int(pcihp_addr + ACPI_PCIHP_SEJ_BASE), 0x04));
649     field = aml_field("SEJ", AML_DWORD_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS);
650     aml_append(field, aml_named_field("B0EJ", 32));
651     aml_append(scope, field);
652 
653     aml_append(scope,
654         aml_operation_region("BNMR", rs,
655                              aml_int(pcihp_addr + ACPI_PCIHP_BNMR_BASE), 0x08));
656     field = aml_field("BNMR", AML_DWORD_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS);
657     aml_append(field, aml_named_field("BNUM", 32));
658     aml_append(field, aml_named_field("PIDX", 32));
659     aml_append(scope, field);
660 
661     aml_append(scope, aml_mutex("BLCK", 0));
662 
663         method = aml_method("PCEJ", 2, AML_NOTSERIALIZED);
664     aml_append(method, aml_acquire(aml_name("BLCK"), 0xFFFF));
665     aml_append(method, aml_store(aml_arg(0), aml_name("BNUM")));
666     aml_append(method,
667         aml_store(aml_shiftleft(aml_int(1), aml_arg(1)), aml_name("B0EJ")));
668     aml_append(method, aml_release(aml_name("BLCK")));
669     aml_append(method, aml_return(aml_int(0)));
670     aml_append(scope, method);
671 
672     method = aml_method("AIDX", 2, AML_NOTSERIALIZED);
673     aml_append(method, aml_acquire(aml_name("BLCK"), 0xFFFF));
674     aml_append(method, aml_store(aml_arg(0), aml_name("BNUM")));
675     aml_append(method,
676         aml_store(aml_shiftleft(aml_int(1), aml_arg(1)), aml_name("PIDX")));
677     aml_append(method, aml_store(aml_name("PIDX"), aml_local(0)));
678     aml_append(method, aml_release(aml_name("BLCK")));
679     aml_append(method, aml_return(aml_local(0)));
680     aml_append(scope, method);
681 
682     aml_append(scope, aml_pci_pdsm());
683 
684     aml_append(table, scope);
685 }
686 
687 /* Reserve PCIHP resources */
688 void build_append_pcihp_resources(Aml *scope /* \\_SB.PCI0 */,
689                                   uint64_t io_addr, uint64_t io_len)
690 {
691     Aml *dev, *crs;
692 
693     dev = aml_device("PHPR");
694     aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A06")));
695     aml_append(dev,
696                aml_name_decl("_UID", aml_string("PCI Hotplug resources")));
697     /* device present, functioning, decoding, not shown in UI */
698     aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
699     crs = aml_resource_template();
700     aml_append(crs, aml_io(AML_DECODE16, io_addr, io_addr, 1, io_len));
701     aml_append(dev, aml_name_decl("_CRS", crs));
702     aml_append(scope, dev);
703 }
704 
705 bool build_append_notification_callback(Aml *parent_scope, const PCIBus *bus)
706 {
707     Aml *method;
708     PCIBus *sec;
709     QObject *bsel;
710     int nr_notifiers = 0;
711     GQueue *pcnt_bus_list = g_queue_new();
712 
713     QLIST_FOREACH(sec, &bus->child, sibling) {
714         Aml *br_scope = aml_scope("S%.02X", sec->parent_dev->devfn);
715         if (pci_bus_is_root(sec)) {
716             continue;
717         }
718         nr_notifiers = nr_notifiers +
719                        build_append_notification_callback(br_scope, sec);
720         /*
721          * add new child scope to parent
722          * and keep track of bus that have PCNT,
723          * bus list is used later to call children PCNTs from this level PCNT
724          */
725         if (nr_notifiers) {
726             g_queue_push_tail(pcnt_bus_list, sec);
727             aml_append(parent_scope, br_scope);
728         }
729     }
730 
731     /*
732      * Append PCNT method to notify about events on local and child buses.
733      * ps: hostbridge might not have hotplug (bsel) enabled but might have
734      * child bridges that do have bsel.
735      */
736     method = aml_method("PCNT", 0, AML_NOTSERIALIZED);
737 
738     /* If bus supports hotplug select it and notify about local events */
739     bsel = object_property_get_qobject(OBJECT(bus), ACPI_PCIHP_PROP_BSEL, NULL);
740     if (bsel) {
741         uint64_t bsel_val = qnum_get_uint(qobject_to(QNum, bsel));
742 
743         aml_append(method, aml_store(aml_int(bsel_val), aml_name("BNUM")));
744         aml_append(method, aml_call2("DVNT", aml_name("PCIU"),
745                                      aml_int(1))); /* Device Check */
746         aml_append(method, aml_call2("DVNT", aml_name("PCID"),
747                                      aml_int(3))); /* Eject Request */
748         nr_notifiers++;
749     }
750 
751     /* Notify about child bus events in any case */
752     while ((sec = g_queue_pop_head(pcnt_bus_list))) {
753         aml_append(method, aml_name("^S%.02X.PCNT", sec->parent_dev->devfn));
754     }
755 
756     aml_append(parent_scope, method);
757     qobject_unref(bsel);
758     g_queue_free(pcnt_bus_list);
759     return !!nr_notifiers;
760 }
761 
762 static Aml *aml_pci_device_dsm(void)
763 {
764     Aml *method;
765 
766     method = aml_method("_DSM", 4, AML_SERIALIZED);
767     {
768         Aml *params = aml_local(0);
769         Aml *pkg = aml_package(2);
770         aml_append(pkg, aml_int(0));
771         aml_append(pkg, aml_int(0));
772         aml_append(method, aml_store(pkg, params));
773         aml_append(method,
774             aml_store(aml_name("BSEL"), aml_index(params, aml_int(0))));
775         aml_append(method,
776             aml_store(aml_name("ASUN"), aml_index(params, aml_int(1))));
777         aml_append(method,
778             aml_return(aml_call5("PDSM", aml_arg(0), aml_arg(1),
779                                  aml_arg(2), aml_arg(3), params))
780         );
781     }
782     return method;
783 }
784 
785 static Aml *aml_pci_static_endpoint_dsm(PCIDevice *pdev)
786 {
787     Aml *method;
788 
789     g_assert(pdev->acpi_index != 0);
790     method = aml_method("_DSM", 4, AML_SERIALIZED);
791     {
792         Aml *params = aml_local(0);
793         Aml *pkg = aml_package(1);
794         aml_append(pkg, aml_int(pdev->acpi_index));
795         aml_append(method, aml_store(pkg, params));
796         aml_append(method,
797             aml_return(aml_call5("EDSM", aml_arg(0), aml_arg(1),
798                                  aml_arg(2), aml_arg(3), params))
799         );
800     }
801     return method;
802 }
803 
804 static void build_append_pcihp_notify_entry(Aml *method, int slot)
805 {
806     Aml *if_ctx;
807     int32_t devfn = PCI_DEVFN(slot, 0);
808 
809     if_ctx = aml_if(aml_and(aml_arg(0), aml_int(0x1U << slot), NULL));
810     aml_append(if_ctx, aml_notify(aml_name("S%.02X", devfn), aml_arg(1)));
811     aml_append(method, if_ctx);
812 }
813 
814 static bool is_devfn_ignored_generic(const int devfn, const PCIBus *bus)
815 {
816     const PCIDevice *pdev = bus->devices[devfn];
817 
818     if (PCI_FUNC(devfn)) {
819         if (IS_PCI_BRIDGE(pdev)) {
820             /*
821              * Ignore only hotplugged PCI bridges on !0 functions, but
822              * allow describing cold plugged bridges on all functions
823              */
824             if (DEVICE(pdev)->hotplugged) {
825                 return true;
826             }
827         }
828     }
829     return false;
830 }
831 
832 static bool is_devfn_ignored_hotplug(const int devfn, const PCIBus *bus)
833 {
834     PCIDevice *pdev = bus->devices[devfn];
835     if (pdev) {
836         return is_devfn_ignored_generic(devfn, bus) ||
837                !DEVICE_GET_CLASS(pdev)->hotpluggable ||
838                /* Cold plugged bridges aren't themselves hot-pluggable */
839                (IS_PCI_BRIDGE(pdev) && !DEVICE(pdev)->hotplugged);
840     } else { /* non populated slots */
841          /*
842           * hotplug is supported only for non-multifunction device
843           * so generate device description only for function 0
844           */
845         if (PCI_FUNC(devfn) ||
846             (pci_bus_is_express(bus) && PCI_SLOT(devfn) > 0)) {
847             return true;
848         }
849     }
850     return false;
851 }
852 
853 void build_append_pcihp_slots(Aml *parent_scope, PCIBus *bus)
854 {
855     int devfn;
856     Aml *dev, *notify_method = NULL, *method;
857     QObject *bsel = object_property_get_qobject(OBJECT(bus),
858                         ACPI_PCIHP_PROP_BSEL, NULL);
859     uint64_t bsel_val = qnum_get_uint(qobject_to(QNum, bsel));
860     qobject_unref(bsel);
861 
862     aml_append(parent_scope, aml_name_decl("BSEL", aml_int(bsel_val)));
863     notify_method = aml_method("DVNT", 2, AML_NOTSERIALIZED);
864 
865     for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
866         int slot = PCI_SLOT(devfn);
867         int adr = slot << 16 | PCI_FUNC(devfn);
868 
869         if (is_devfn_ignored_hotplug(devfn, bus)) {
870             continue;
871         }
872 
873         if (bus->devices[devfn]) {
874             dev = aml_scope("S%.02X", devfn);
875         } else {
876             dev = aml_device("S%.02X", devfn);
877             aml_append(dev, aml_name_decl("_ADR", aml_int(adr)));
878         }
879 
880         /*
881          * Can't declare _SUN here for every device as it changes 'slot'
882          * enumeration order in linux kernel, so use another variable for it
883          */
884         aml_append(dev, aml_name_decl("ASUN", aml_int(slot)));
885         aml_append(dev, aml_pci_device_dsm());
886 
887         aml_append(dev, aml_name_decl("_SUN", aml_int(slot)));
888         /* add _EJ0 to make slot hotpluggable  */
889         method = aml_method("_EJ0", 1, AML_NOTSERIALIZED);
890         aml_append(method,
891             aml_call2("PCEJ", aml_name("BSEL"), aml_name("_SUN"))
892         );
893         aml_append(dev, method);
894 
895         build_append_pcihp_notify_entry(notify_method, slot);
896 
897         /* device descriptor has been composed, add it into parent context */
898         aml_append(parent_scope, dev);
899     }
900     aml_append(parent_scope, notify_method);
901 }
902 
903 void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus)
904 {
905     int devfn;
906     Aml *dev;
907 
908     for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
909         /* ACPI spec: 1.0b: Table 6-2 _ADR Object Bus Types, PCI type */
910         int adr = PCI_SLOT(devfn) << 16 | PCI_FUNC(devfn);
911         PCIDevice *pdev = bus->devices[devfn];
912 
913         if (!pdev || is_devfn_ignored_generic(devfn, bus)) {
914             continue;
915         }
916 
917         /* start to compose PCI device descriptor */
918         dev = aml_device("S%.02X", devfn);
919         aml_append(dev, aml_name_decl("_ADR", aml_int(adr)));
920 
921         call_dev_aml_func(DEVICE(bus->devices[devfn]), dev);
922         /* add _DSM if device has acpi-index set */
923         if (pdev->acpi_index &&
924             !object_property_get_bool(OBJECT(pdev), "hotpluggable",
925                                       &error_abort)) {
926             aml_append(dev, aml_pci_static_endpoint_dsm(pdev));
927         }
928 
929         /* device descriptor has been composed, add it into parent context */
930         aml_append(parent_scope, dev);
931     }
932 }
933 
934 const VMStateDescription vmstate_acpi_pcihp_pci_status = {
935     .name = "acpi_pcihp_pci_status",
936     .version_id = 1,
937     .minimum_version_id = 1,
938     .fields = (const VMStateField[]) {
939         VMSTATE_UINT32(up, AcpiPciHpPciStatus),
940         VMSTATE_UINT32(down, AcpiPciHpPciStatus),
941         VMSTATE_END_OF_LIST()
942     }
943 };
944