2
0

pcihp.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  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.txt
  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 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. #include "qemu/osdep.h"
  27. #include "hw/acpi/pcihp.h"
  28. #include "hw/pci-host/i440fx.h"
  29. #include "hw/pci/pci.h"
  30. #include "hw/pci/pci_bridge.h"
  31. #include "hw/acpi/acpi.h"
  32. #include "exec/address-spaces.h"
  33. #include "hw/pci/pci_bus.h"
  34. #include "migration/vmstate.h"
  35. #include "qapi/error.h"
  36. #include "qom/qom-qobject.h"
  37. #include "trace.h"
  38. #define ACPI_PCIHP_ADDR 0xae00
  39. #define ACPI_PCIHP_SIZE 0x0014
  40. #define PCI_UP_BASE 0x0000
  41. #define PCI_DOWN_BASE 0x0004
  42. #define PCI_EJ_BASE 0x0008
  43. #define PCI_RMV_BASE 0x000c
  44. #define PCI_SEL_BASE 0x0010
  45. typedef struct AcpiPciHpFind {
  46. int bsel;
  47. PCIBus *bus;
  48. } AcpiPciHpFind;
  49. static int acpi_pcihp_get_bsel(PCIBus *bus)
  50. {
  51. Error *local_err = NULL;
  52. uint64_t bsel = object_property_get_uint(OBJECT(bus), ACPI_PCIHP_PROP_BSEL,
  53. &local_err);
  54. if (local_err || bsel >= ACPI_PCIHP_MAX_HOTPLUG_BUS) {
  55. if (local_err) {
  56. error_free(local_err);
  57. }
  58. return -1;
  59. } else {
  60. return bsel;
  61. }
  62. }
  63. /* Assign BSEL property to all buses. In the future, this can be changed
  64. * to only assign to buses that support hotplug.
  65. */
  66. static void *acpi_set_bsel(PCIBus *bus, void *opaque)
  67. {
  68. unsigned *bsel_alloc = opaque;
  69. unsigned *bus_bsel;
  70. if (qbus_is_hotpluggable(BUS(bus))) {
  71. bus_bsel = g_malloc(sizeof *bus_bsel);
  72. *bus_bsel = (*bsel_alloc)++;
  73. object_property_add_uint32_ptr(OBJECT(bus), ACPI_PCIHP_PROP_BSEL,
  74. bus_bsel, &error_abort);
  75. }
  76. return bsel_alloc;
  77. }
  78. static void acpi_set_pci_info(void)
  79. {
  80. static bool bsel_is_set;
  81. PCIBus *bus;
  82. unsigned bsel_alloc = ACPI_PCIHP_BSEL_DEFAULT;
  83. if (bsel_is_set) {
  84. return;
  85. }
  86. bsel_is_set = true;
  87. bus = find_i440fx(); /* TODO: Q35 support */
  88. if (bus) {
  89. /* Scan all PCI buses. Set property to enable acpi based hotplug. */
  90. pci_for_each_bus_depth_first(bus, acpi_set_bsel, NULL, &bsel_alloc);
  91. }
  92. }
  93. static void acpi_pcihp_test_hotplug_bus(PCIBus *bus, void *opaque)
  94. {
  95. AcpiPciHpFind *find = opaque;
  96. if (find->bsel == acpi_pcihp_get_bsel(bus)) {
  97. find->bus = bus;
  98. }
  99. }
  100. static PCIBus *acpi_pcihp_find_hotplug_bus(AcpiPciHpState *s, int bsel)
  101. {
  102. AcpiPciHpFind find = { .bsel = bsel, .bus = NULL };
  103. if (bsel < 0) {
  104. return NULL;
  105. }
  106. pci_for_each_bus(s->root, acpi_pcihp_test_hotplug_bus, &find);
  107. /* Make bsel 0 eject root bus if bsel property is not set,
  108. * for compatibility with non acpi setups.
  109. * TODO: really needed?
  110. */
  111. if (!bsel && !find.bus) {
  112. find.bus = s->root;
  113. }
  114. return find.bus;
  115. }
  116. static bool acpi_pcihp_pc_no_hotplug(AcpiPciHpState *s, PCIDevice *dev)
  117. {
  118. PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
  119. DeviceClass *dc = DEVICE_GET_CLASS(dev);
  120. /*
  121. * ACPI doesn't allow hotplug of bridge devices. Don't allow
  122. * hot-unplug of bridge devices unless they were added by hotplug
  123. * (and so, not described by acpi).
  124. */
  125. return (pc->is_bridge && !dev->qdev.hotplugged) || !dc->hotpluggable;
  126. }
  127. static void acpi_pcihp_eject_slot(AcpiPciHpState *s, unsigned bsel, unsigned slots)
  128. {
  129. HotplugHandler *hotplug_ctrl;
  130. BusChild *kid, *next;
  131. int slot = ctz32(slots);
  132. PCIBus *bus = acpi_pcihp_find_hotplug_bus(s, bsel);
  133. trace_acpi_pci_eject_slot(bsel, slot);
  134. if (!bus) {
  135. return;
  136. }
  137. /* Mark request as complete */
  138. s->acpi_pcihp_pci_status[bsel].down &= ~(1U << slot);
  139. s->acpi_pcihp_pci_status[bsel].up &= ~(1U << slot);
  140. QTAILQ_FOREACH_SAFE(kid, &bus->qbus.children, sibling, next) {
  141. DeviceState *qdev = kid->child;
  142. PCIDevice *dev = PCI_DEVICE(qdev);
  143. if (PCI_SLOT(dev->devfn) == slot) {
  144. if (!acpi_pcihp_pc_no_hotplug(s, dev)) {
  145. hotplug_ctrl = qdev_get_hotplug_handler(qdev);
  146. hotplug_handler_unplug(hotplug_ctrl, qdev, &error_abort);
  147. object_unparent(OBJECT(qdev));
  148. }
  149. }
  150. }
  151. }
  152. static void acpi_pcihp_update_hotplug_bus(AcpiPciHpState *s, int bsel)
  153. {
  154. BusChild *kid, *next;
  155. PCIBus *bus = acpi_pcihp_find_hotplug_bus(s, bsel);
  156. /* Execute any pending removes during reset */
  157. while (s->acpi_pcihp_pci_status[bsel].down) {
  158. acpi_pcihp_eject_slot(s, bsel, s->acpi_pcihp_pci_status[bsel].down);
  159. }
  160. s->acpi_pcihp_pci_status[bsel].hotplug_enable = ~0;
  161. if (!bus) {
  162. return;
  163. }
  164. QTAILQ_FOREACH_SAFE(kid, &bus->qbus.children, sibling, next) {
  165. DeviceState *qdev = kid->child;
  166. PCIDevice *pdev = PCI_DEVICE(qdev);
  167. int slot = PCI_SLOT(pdev->devfn);
  168. if (acpi_pcihp_pc_no_hotplug(s, pdev)) {
  169. s->acpi_pcihp_pci_status[bsel].hotplug_enable &= ~(1U << slot);
  170. }
  171. }
  172. }
  173. static void acpi_pcihp_update(AcpiPciHpState *s)
  174. {
  175. int i;
  176. for (i = 0; i < ACPI_PCIHP_MAX_HOTPLUG_BUS; ++i) {
  177. acpi_pcihp_update_hotplug_bus(s, i);
  178. }
  179. }
  180. void acpi_pcihp_reset(AcpiPciHpState *s)
  181. {
  182. acpi_set_pci_info();
  183. acpi_pcihp_update(s);
  184. }
  185. void acpi_pcihp_device_pre_plug_cb(HotplugHandler *hotplug_dev,
  186. DeviceState *dev, Error **errp)
  187. {
  188. /* Only hotplugged devices need the hotplug capability. */
  189. if (dev->hotplugged &&
  190. acpi_pcihp_get_bsel(pci_get_bus(PCI_DEVICE(dev))) < 0) {
  191. error_setg(errp, "Unsupported bus. Bus doesn't have property '"
  192. ACPI_PCIHP_PROP_BSEL "' set");
  193. return;
  194. }
  195. }
  196. void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
  197. DeviceState *dev, Error **errp)
  198. {
  199. PCIDevice *pdev = PCI_DEVICE(dev);
  200. int slot = PCI_SLOT(pdev->devfn);
  201. int bsel;
  202. /* Don't send event when device is enabled during qemu machine creation:
  203. * it is present on boot, no hotplug event is necessary. We do send an
  204. * event when the device is disabled later. */
  205. if (!dev->hotplugged) {
  206. /*
  207. * Overwrite the default hotplug handler with the ACPI PCI one
  208. * for cold plugged bridges only.
  209. */
  210. if (!s->legacy_piix &&
  211. object_dynamic_cast(OBJECT(dev), TYPE_PCI_BRIDGE)) {
  212. PCIBus *sec = pci_bridge_get_sec_bus(PCI_BRIDGE(pdev));
  213. qbus_set_hotplug_handler(BUS(sec), OBJECT(hotplug_dev),
  214. &error_abort);
  215. /* We don't have to overwrite any other hotplug handler yet */
  216. assert(QLIST_EMPTY(&sec->child));
  217. }
  218. return;
  219. }
  220. bsel = acpi_pcihp_get_bsel(pci_get_bus(pdev));
  221. g_assert(bsel >= 0);
  222. s->acpi_pcihp_pci_status[bsel].up |= (1U << slot);
  223. acpi_send_event(DEVICE(hotplug_dev), ACPI_PCI_HOTPLUG_STATUS);
  224. }
  225. void acpi_pcihp_device_unplug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
  226. DeviceState *dev, Error **errp)
  227. {
  228. trace_acpi_pci_unplug(PCI_SLOT(PCI_DEVICE(dev)->devfn),
  229. acpi_pcihp_get_bsel(pci_get_bus(PCI_DEVICE(dev))));
  230. object_property_set_bool(OBJECT(dev), false, "realized", NULL);
  231. }
  232. void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev,
  233. AcpiPciHpState *s, DeviceState *dev,
  234. Error **errp)
  235. {
  236. PCIDevice *pdev = PCI_DEVICE(dev);
  237. int slot = PCI_SLOT(pdev->devfn);
  238. int bsel = acpi_pcihp_get_bsel(pci_get_bus(pdev));
  239. trace_acpi_pci_unplug_request(bsel, slot);
  240. if (bsel < 0) {
  241. error_setg(errp, "Unsupported bus. Bus doesn't have property '"
  242. ACPI_PCIHP_PROP_BSEL "' set");
  243. return;
  244. }
  245. s->acpi_pcihp_pci_status[bsel].down |= (1U << slot);
  246. acpi_send_event(DEVICE(hotplug_dev), ACPI_PCI_HOTPLUG_STATUS);
  247. }
  248. static uint64_t pci_read(void *opaque, hwaddr addr, unsigned int size)
  249. {
  250. AcpiPciHpState *s = opaque;
  251. uint32_t val = 0;
  252. int bsel = s->hotplug_select;
  253. if (bsel < 0 || bsel >= ACPI_PCIHP_MAX_HOTPLUG_BUS) {
  254. return 0;
  255. }
  256. switch (addr) {
  257. case PCI_UP_BASE:
  258. val = s->acpi_pcihp_pci_status[bsel].up;
  259. if (!s->legacy_piix) {
  260. s->acpi_pcihp_pci_status[bsel].up = 0;
  261. }
  262. trace_acpi_pci_up_read(val);
  263. break;
  264. case PCI_DOWN_BASE:
  265. val = s->acpi_pcihp_pci_status[bsel].down;
  266. trace_acpi_pci_down_read(val);
  267. break;
  268. case PCI_EJ_BASE:
  269. /* No feature defined yet */
  270. trace_acpi_pci_features_read(val);
  271. break;
  272. case PCI_RMV_BASE:
  273. val = s->acpi_pcihp_pci_status[bsel].hotplug_enable;
  274. trace_acpi_pci_rmv_read(val);
  275. break;
  276. case PCI_SEL_BASE:
  277. val = s->hotplug_select;
  278. trace_acpi_pci_sel_read(val);
  279. default:
  280. break;
  281. }
  282. return val;
  283. }
  284. static void pci_write(void *opaque, hwaddr addr, uint64_t data,
  285. unsigned int size)
  286. {
  287. AcpiPciHpState *s = opaque;
  288. switch (addr) {
  289. case PCI_EJ_BASE:
  290. if (s->hotplug_select >= ACPI_PCIHP_MAX_HOTPLUG_BUS) {
  291. break;
  292. }
  293. acpi_pcihp_eject_slot(s, s->hotplug_select, data);
  294. trace_acpi_pci_ej_write(addr, data);
  295. break;
  296. case PCI_SEL_BASE:
  297. s->hotplug_select = s->legacy_piix ? ACPI_PCIHP_BSEL_DEFAULT : data;
  298. trace_acpi_pci_sel_write(addr, data);
  299. default:
  300. break;
  301. }
  302. }
  303. static const MemoryRegionOps acpi_pcihp_io_ops = {
  304. .read = pci_read,
  305. .write = pci_write,
  306. .endianness = DEVICE_LITTLE_ENDIAN,
  307. .valid = {
  308. .min_access_size = 4,
  309. .max_access_size = 4,
  310. },
  311. };
  312. void acpi_pcihp_init(Object *owner, AcpiPciHpState *s, PCIBus *root_bus,
  313. MemoryRegion *address_space_io, bool bridges_enabled)
  314. {
  315. s->io_len = ACPI_PCIHP_SIZE;
  316. s->io_base = ACPI_PCIHP_ADDR;
  317. s->root= root_bus;
  318. s->legacy_piix = !bridges_enabled;
  319. memory_region_init_io(&s->io, owner, &acpi_pcihp_io_ops, s,
  320. "acpi-pci-hotplug", s->io_len);
  321. memory_region_add_subregion(address_space_io, s->io_base, &s->io);
  322. object_property_add_uint16_ptr(owner, ACPI_PCIHP_IO_BASE_PROP, &s->io_base,
  323. &error_abort);
  324. object_property_add_uint16_ptr(owner, ACPI_PCIHP_IO_LEN_PROP, &s->io_len,
  325. &error_abort);
  326. }
  327. const VMStateDescription vmstate_acpi_pcihp_pci_status = {
  328. .name = "acpi_pcihp_pci_status",
  329. .version_id = 1,
  330. .minimum_version_id = 1,
  331. .fields = (VMStateField[]) {
  332. VMSTATE_UINT32(up, AcpiPciHpPciStatus),
  333. VMSTATE_UINT32(down, AcpiPciHpPciStatus),
  334. VMSTATE_END_OF_LIST()
  335. }
  336. };