piix.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754
  1. /*
  2. * QEMU i440FX/PIIX3 PCI Bridge Emulation
  3. *
  4. * Copyright (c) 2006 Fabrice Bellard
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. */
  24. #include "hw/hw.h"
  25. #include "hw/i386/pc.h"
  26. #include "hw/pci/pci.h"
  27. #include "hw/pci/pci_host.h"
  28. #include "hw/isa/isa.h"
  29. #include "hw/sysbus.h"
  30. #include "qemu/range.h"
  31. #include "hw/xen/xen.h"
  32. #include "hw/pci-host/pam.h"
  33. #include "sysemu/sysemu.h"
  34. #include "hw/i386/ioapic.h"
  35. #include "qapi/visitor.h"
  36. /*
  37. * I440FX chipset data sheet.
  38. * http://download.intel.com/design/chipsets/datashts/29054901.pdf
  39. */
  40. #define TYPE_I440FX_PCI_HOST_BRIDGE "i440FX-pcihost"
  41. #define I440FX_PCI_HOST_BRIDGE(obj) \
  42. OBJECT_CHECK(I440FXState, (obj), TYPE_I440FX_PCI_HOST_BRIDGE)
  43. typedef struct I440FXState {
  44. PCIHostState parent_obj;
  45. PcPciInfo pci_info;
  46. uint64_t pci_hole64_size;
  47. uint32_t short_root_bus;
  48. } I440FXState;
  49. #define PIIX_NUM_PIC_IRQS 16 /* i8259 * 2 */
  50. #define PIIX_NUM_PIRQS 4ULL /* PIRQ[A-D] */
  51. #define XEN_PIIX_NUM_PIRQS 128ULL
  52. #define PIIX_PIRQC 0x60
  53. /*
  54. * Reset Control Register: PCI-accessible ISA-Compatible Register at address
  55. * 0xcf9, provided by the PCI/ISA bridge (PIIX3 PCI function 0, 8086:7000).
  56. */
  57. #define RCR_IOPORT 0xcf9
  58. typedef struct PIIX3State {
  59. PCIDevice dev;
  60. /*
  61. * bitmap to track pic levels.
  62. * The pic level is the logical OR of all the PCI irqs mapped to it
  63. * So one PIC level is tracked by PIIX_NUM_PIRQS bits.
  64. *
  65. * PIRQ is mapped to PIC pins, we track it by
  66. * PIIX_NUM_PIRQS * PIIX_NUM_PIC_IRQS = 64 bits with
  67. * pic_irq * PIIX_NUM_PIRQS + pirq
  68. */
  69. #if PIIX_NUM_PIC_IRQS * PIIX_NUM_PIRQS > 64
  70. #error "unable to encode pic state in 64bit in pic_levels."
  71. #endif
  72. uint64_t pic_levels;
  73. qemu_irq *pic;
  74. /* This member isn't used. Just for save/load compatibility */
  75. int32_t pci_irq_levels_vmstate[PIIX_NUM_PIRQS];
  76. /* Reset Control Register contents */
  77. uint8_t rcr;
  78. /* IO memory region for Reset Control Register (RCR_IOPORT) */
  79. MemoryRegion rcr_mem;
  80. } PIIX3State;
  81. #define TYPE_I440FX_PCI_DEVICE "i440FX"
  82. #define I440FX_PCI_DEVICE(obj) \
  83. OBJECT_CHECK(PCII440FXState, (obj), TYPE_I440FX_PCI_DEVICE)
  84. struct PCII440FXState {
  85. /*< private >*/
  86. PCIDevice parent_obj;
  87. /*< public >*/
  88. MemoryRegion *system_memory;
  89. MemoryRegion *pci_address_space;
  90. MemoryRegion *ram_memory;
  91. PAMMemoryRegion pam_regions[13];
  92. MemoryRegion smram_region;
  93. uint8_t smm_enabled;
  94. };
  95. #define I440FX_PAM 0x59
  96. #define I440FX_PAM_SIZE 7
  97. #define I440FX_SMRAM 0x72
  98. static void piix3_set_irq(void *opaque, int pirq, int level);
  99. static PCIINTxRoute piix3_route_intx_pin_to_irq(void *opaque, int pci_intx);
  100. static void piix3_write_config_xen(PCIDevice *dev,
  101. uint32_t address, uint32_t val, int len);
  102. /* return the global irq number corresponding to a given device irq
  103. pin. We could also use the bus number to have a more precise
  104. mapping. */
  105. static int pci_slot_get_pirq(PCIDevice *pci_dev, int pci_intx)
  106. {
  107. int slot_addend;
  108. slot_addend = (pci_dev->devfn >> 3) - 1;
  109. return (pci_intx + slot_addend) & 3;
  110. }
  111. static void i440fx_update_memory_mappings(PCII440FXState *d)
  112. {
  113. int i;
  114. PCIDevice *pd = PCI_DEVICE(d);
  115. memory_region_transaction_begin();
  116. for (i = 0; i < 13; i++) {
  117. pam_update(&d->pam_regions[i], i,
  118. pd->config[I440FX_PAM + ((i + 1) / 2)]);
  119. }
  120. smram_update(&d->smram_region, pd->config[I440FX_SMRAM], d->smm_enabled);
  121. memory_region_transaction_commit();
  122. }
  123. static void i440fx_set_smm(int val, void *arg)
  124. {
  125. PCII440FXState *d = arg;
  126. PCIDevice *pd = PCI_DEVICE(d);
  127. memory_region_transaction_begin();
  128. smram_set_smm(&d->smm_enabled, val, pd->config[I440FX_SMRAM],
  129. &d->smram_region);
  130. memory_region_transaction_commit();
  131. }
  132. static void i440fx_write_config(PCIDevice *dev,
  133. uint32_t address, uint32_t val, int len)
  134. {
  135. PCII440FXState *d = I440FX_PCI_DEVICE(dev);
  136. /* XXX: implement SMRAM.D_LOCK */
  137. pci_default_write_config(dev, address, val, len);
  138. if (ranges_overlap(address, len, I440FX_PAM, I440FX_PAM_SIZE) ||
  139. range_covers_byte(address, len, I440FX_SMRAM)) {
  140. i440fx_update_memory_mappings(d);
  141. }
  142. }
  143. static int i440fx_load_old(QEMUFile* f, void *opaque, int version_id)
  144. {
  145. PCII440FXState *d = opaque;
  146. PCIDevice *pd = PCI_DEVICE(d);
  147. int ret, i;
  148. ret = pci_device_load(pd, f);
  149. if (ret < 0)
  150. return ret;
  151. i440fx_update_memory_mappings(d);
  152. qemu_get_8s(f, &d->smm_enabled);
  153. if (version_id == 2) {
  154. for (i = 0; i < PIIX_NUM_PIRQS; i++) {
  155. qemu_get_be32(f); /* dummy load for compatibility */
  156. }
  157. }
  158. return 0;
  159. }
  160. static int i440fx_post_load(void *opaque, int version_id)
  161. {
  162. PCII440FXState *d = opaque;
  163. i440fx_update_memory_mappings(d);
  164. return 0;
  165. }
  166. static const VMStateDescription vmstate_i440fx = {
  167. .name = "I440FX",
  168. .version_id = 3,
  169. .minimum_version_id = 3,
  170. .minimum_version_id_old = 1,
  171. .load_state_old = i440fx_load_old,
  172. .post_load = i440fx_post_load,
  173. .fields = (VMStateField []) {
  174. VMSTATE_PCI_DEVICE(parent_obj, PCII440FXState),
  175. VMSTATE_UINT8(smm_enabled, PCII440FXState),
  176. VMSTATE_END_OF_LIST()
  177. }
  178. };
  179. static void i440fx_pcihost_get_pci_hole_start(Object *obj, Visitor *v,
  180. void *opaque, const char *name,
  181. Error **errp)
  182. {
  183. I440FXState *s = I440FX_PCI_HOST_BRIDGE(obj);
  184. uint32_t value = s->pci_info.w32.begin;
  185. visit_type_uint32(v, &value, name, errp);
  186. }
  187. static void i440fx_pcihost_get_pci_hole_end(Object *obj, Visitor *v,
  188. void *opaque, const char *name,
  189. Error **errp)
  190. {
  191. I440FXState *s = I440FX_PCI_HOST_BRIDGE(obj);
  192. uint32_t value = s->pci_info.w32.end;
  193. visit_type_uint32(v, &value, name, errp);
  194. }
  195. static void i440fx_pcihost_get_pci_hole64_start(Object *obj, Visitor *v,
  196. void *opaque, const char *name,
  197. Error **errp)
  198. {
  199. PCIHostState *h = PCI_HOST_BRIDGE(obj);
  200. Range w64;
  201. pci_bus_get_w64_range(h->bus, &w64);
  202. visit_type_uint64(v, &w64.begin, name, errp);
  203. }
  204. static void i440fx_pcihost_get_pci_hole64_end(Object *obj, Visitor *v,
  205. void *opaque, const char *name,
  206. Error **errp)
  207. {
  208. PCIHostState *h = PCI_HOST_BRIDGE(obj);
  209. Range w64;
  210. pci_bus_get_w64_range(h->bus, &w64);
  211. visit_type_uint64(v, &w64.end, name, errp);
  212. }
  213. static void i440fx_pcihost_initfn(Object *obj)
  214. {
  215. PCIHostState *s = PCI_HOST_BRIDGE(obj);
  216. I440FXState *d = I440FX_PCI_HOST_BRIDGE(obj);
  217. memory_region_init_io(&s->conf_mem, obj, &pci_host_conf_le_ops, s,
  218. "pci-conf-idx", 4);
  219. memory_region_init_io(&s->data_mem, obj, &pci_host_data_le_ops, s,
  220. "pci-conf-data", 4);
  221. object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "int",
  222. i440fx_pcihost_get_pci_hole_start,
  223. NULL, NULL, NULL, NULL);
  224. object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_END, "int",
  225. i440fx_pcihost_get_pci_hole_end,
  226. NULL, NULL, NULL, NULL);
  227. object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_START, "int",
  228. i440fx_pcihost_get_pci_hole64_start,
  229. NULL, NULL, NULL, NULL);
  230. object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_END, "int",
  231. i440fx_pcihost_get_pci_hole64_end,
  232. NULL, NULL, NULL, NULL);
  233. d->pci_info.w32.end = IO_APIC_DEFAULT_ADDRESS;
  234. }
  235. static void i440fx_pcihost_realize(DeviceState *dev, Error **errp)
  236. {
  237. PCIHostState *s = PCI_HOST_BRIDGE(dev);
  238. SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
  239. sysbus_add_io(sbd, 0xcf8, &s->conf_mem);
  240. sysbus_init_ioports(sbd, 0xcf8, 4);
  241. sysbus_add_io(sbd, 0xcfc, &s->data_mem);
  242. sysbus_init_ioports(sbd, 0xcfc, 4);
  243. }
  244. static int i440fx_initfn(PCIDevice *dev)
  245. {
  246. PCII440FXState *d = I440FX_PCI_DEVICE(dev);
  247. dev->config[I440FX_SMRAM] = 0x02;
  248. cpu_smm_register(&i440fx_set_smm, d);
  249. return 0;
  250. }
  251. PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
  252. int *piix3_devfn,
  253. ISABus **isa_bus, qemu_irq *pic,
  254. MemoryRegion *address_space_mem,
  255. MemoryRegion *address_space_io,
  256. ram_addr_t ram_size,
  257. ram_addr_t below_4g_mem_size,
  258. ram_addr_t above_4g_mem_size,
  259. MemoryRegion *pci_address_space,
  260. MemoryRegion *ram_memory)
  261. {
  262. DeviceState *dev;
  263. PCIBus *b;
  264. PCIDevice *d;
  265. PCIHostState *s;
  266. PIIX3State *piix3;
  267. PCII440FXState *f;
  268. unsigned i;
  269. I440FXState *i440fx;
  270. dev = qdev_create(NULL, TYPE_I440FX_PCI_HOST_BRIDGE);
  271. s = PCI_HOST_BRIDGE(dev);
  272. b = pci_bus_new(dev, NULL, pci_address_space,
  273. address_space_io, 0, TYPE_PCI_BUS);
  274. s->bus = b;
  275. object_property_add_child(qdev_get_machine(), "i440fx", OBJECT(dev), NULL);
  276. qdev_init_nofail(dev);
  277. d = pci_create_simple(b, 0, TYPE_I440FX_PCI_DEVICE);
  278. *pi440fx_state = I440FX_PCI_DEVICE(d);
  279. f = *pi440fx_state;
  280. f->system_memory = address_space_mem;
  281. f->pci_address_space = pci_address_space;
  282. f->ram_memory = ram_memory;
  283. i440fx = I440FX_PCI_HOST_BRIDGE(dev);
  284. i440fx->pci_info.w32.begin = below_4g_mem_size;
  285. /* setup pci memory mapping */
  286. pc_pci_as_mapping_init(OBJECT(f), f->system_memory,
  287. f->pci_address_space);
  288. memory_region_init_alias(&f->smram_region, OBJECT(d), "smram-region",
  289. f->pci_address_space, 0xa0000, 0x20000);
  290. memory_region_add_subregion_overlap(f->system_memory, 0xa0000,
  291. &f->smram_region, 1);
  292. memory_region_set_enabled(&f->smram_region, false);
  293. init_pam(dev, f->ram_memory, f->system_memory, f->pci_address_space,
  294. &f->pam_regions[0], PAM_BIOS_BASE, PAM_BIOS_SIZE);
  295. for (i = 0; i < 12; ++i) {
  296. init_pam(dev, f->ram_memory, f->system_memory, f->pci_address_space,
  297. &f->pam_regions[i+1], PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE,
  298. PAM_EXPAN_SIZE);
  299. }
  300. /* Xen supports additional interrupt routes from the PCI devices to
  301. * the IOAPIC: the four pins of each PCI device on the bus are also
  302. * connected to the IOAPIC directly.
  303. * These additional routes can be discovered through ACPI. */
  304. if (xen_enabled()) {
  305. piix3 = DO_UPCAST(PIIX3State, dev,
  306. pci_create_simple_multifunction(b, -1, true, "PIIX3-xen"));
  307. pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq,
  308. piix3, XEN_PIIX_NUM_PIRQS);
  309. } else {
  310. piix3 = DO_UPCAST(PIIX3State, dev,
  311. pci_create_simple_multifunction(b, -1, true, "PIIX3"));
  312. pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3,
  313. PIIX_NUM_PIRQS);
  314. pci_bus_set_route_irq_fn(b, piix3_route_intx_pin_to_irq);
  315. }
  316. piix3->pic = pic;
  317. *isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(piix3), "isa.0"));
  318. *piix3_devfn = piix3->dev.devfn;
  319. ram_size = ram_size / 8 / 1024 / 1024;
  320. if (ram_size > 255) {
  321. ram_size = 255;
  322. }
  323. d->config[0x57] = ram_size;
  324. i440fx_update_memory_mappings(f);
  325. return b;
  326. }
  327. PCIBus *find_i440fx(void)
  328. {
  329. PCIHostState *s = OBJECT_CHECK(PCIHostState,
  330. object_resolve_path("/machine/i440fx", NULL),
  331. TYPE_PCI_HOST_BRIDGE);
  332. return s ? s->bus : NULL;
  333. }
  334. /* PIIX3 PCI to ISA bridge */
  335. static void piix3_set_irq_pic(PIIX3State *piix3, int pic_irq)
  336. {
  337. qemu_set_irq(piix3->pic[pic_irq],
  338. !!(piix3->pic_levels &
  339. (((1ULL << PIIX_NUM_PIRQS) - 1) <<
  340. (pic_irq * PIIX_NUM_PIRQS))));
  341. }
  342. static void piix3_set_irq_level(PIIX3State *piix3, int pirq, int level)
  343. {
  344. int pic_irq;
  345. uint64_t mask;
  346. pic_irq = piix3->dev.config[PIIX_PIRQC + pirq];
  347. if (pic_irq >= PIIX_NUM_PIC_IRQS) {
  348. return;
  349. }
  350. mask = 1ULL << ((pic_irq * PIIX_NUM_PIRQS) + pirq);
  351. piix3->pic_levels &= ~mask;
  352. piix3->pic_levels |= mask * !!level;
  353. piix3_set_irq_pic(piix3, pic_irq);
  354. }
  355. static void piix3_set_irq(void *opaque, int pirq, int level)
  356. {
  357. PIIX3State *piix3 = opaque;
  358. piix3_set_irq_level(piix3, pirq, level);
  359. }
  360. static PCIINTxRoute piix3_route_intx_pin_to_irq(void *opaque, int pin)
  361. {
  362. PIIX3State *piix3 = opaque;
  363. int irq = piix3->dev.config[PIIX_PIRQC + pin];
  364. PCIINTxRoute route;
  365. if (irq < PIIX_NUM_PIC_IRQS) {
  366. route.mode = PCI_INTX_ENABLED;
  367. route.irq = irq;
  368. } else {
  369. route.mode = PCI_INTX_DISABLED;
  370. route.irq = -1;
  371. }
  372. return route;
  373. }
  374. /* irq routing is changed. so rebuild bitmap */
  375. static void piix3_update_irq_levels(PIIX3State *piix3)
  376. {
  377. int pirq;
  378. piix3->pic_levels = 0;
  379. for (pirq = 0; pirq < PIIX_NUM_PIRQS; pirq++) {
  380. piix3_set_irq_level(piix3, pirq,
  381. pci_bus_get_irq_level(piix3->dev.bus, pirq));
  382. }
  383. }
  384. static void piix3_write_config(PCIDevice *dev,
  385. uint32_t address, uint32_t val, int len)
  386. {
  387. pci_default_write_config(dev, address, val, len);
  388. if (ranges_overlap(address, len, PIIX_PIRQC, 4)) {
  389. PIIX3State *piix3 = DO_UPCAST(PIIX3State, dev, dev);
  390. int pic_irq;
  391. pci_bus_fire_intx_routing_notifier(piix3->dev.bus);
  392. piix3_update_irq_levels(piix3);
  393. for (pic_irq = 0; pic_irq < PIIX_NUM_PIC_IRQS; pic_irq++) {
  394. piix3_set_irq_pic(piix3, pic_irq);
  395. }
  396. }
  397. }
  398. static void piix3_write_config_xen(PCIDevice *dev,
  399. uint32_t address, uint32_t val, int len)
  400. {
  401. xen_piix_pci_write_config_client(address, val, len);
  402. piix3_write_config(dev, address, val, len);
  403. }
  404. static void piix3_reset(void *opaque)
  405. {
  406. PIIX3State *d = opaque;
  407. uint8_t *pci_conf = d->dev.config;
  408. pci_conf[0x04] = 0x07; /* master, memory and I/O */
  409. pci_conf[0x05] = 0x00;
  410. pci_conf[0x06] = 0x00;
  411. pci_conf[0x07] = 0x02; /* PCI_status_devsel_medium */
  412. pci_conf[0x4c] = 0x4d;
  413. pci_conf[0x4e] = 0x03;
  414. pci_conf[0x4f] = 0x00;
  415. pci_conf[0x60] = 0x80;
  416. pci_conf[0x61] = 0x80;
  417. pci_conf[0x62] = 0x80;
  418. pci_conf[0x63] = 0x80;
  419. pci_conf[0x69] = 0x02;
  420. pci_conf[0x70] = 0x80;
  421. pci_conf[0x76] = 0x0c;
  422. pci_conf[0x77] = 0x0c;
  423. pci_conf[0x78] = 0x02;
  424. pci_conf[0x79] = 0x00;
  425. pci_conf[0x80] = 0x00;
  426. pci_conf[0x82] = 0x00;
  427. pci_conf[0xa0] = 0x08;
  428. pci_conf[0xa2] = 0x00;
  429. pci_conf[0xa3] = 0x00;
  430. pci_conf[0xa4] = 0x00;
  431. pci_conf[0xa5] = 0x00;
  432. pci_conf[0xa6] = 0x00;
  433. pci_conf[0xa7] = 0x00;
  434. pci_conf[0xa8] = 0x0f;
  435. pci_conf[0xaa] = 0x00;
  436. pci_conf[0xab] = 0x00;
  437. pci_conf[0xac] = 0x00;
  438. pci_conf[0xae] = 0x00;
  439. d->pic_levels = 0;
  440. d->rcr = 0;
  441. }
  442. static int piix3_post_load(void *opaque, int version_id)
  443. {
  444. PIIX3State *piix3 = opaque;
  445. piix3_update_irq_levels(piix3);
  446. return 0;
  447. }
  448. static void piix3_pre_save(void *opaque)
  449. {
  450. int i;
  451. PIIX3State *piix3 = opaque;
  452. for (i = 0; i < ARRAY_SIZE(piix3->pci_irq_levels_vmstate); i++) {
  453. piix3->pci_irq_levels_vmstate[i] =
  454. pci_bus_get_irq_level(piix3->dev.bus, i);
  455. }
  456. }
  457. static bool piix3_rcr_needed(void *opaque)
  458. {
  459. PIIX3State *piix3 = opaque;
  460. return (piix3->rcr != 0);
  461. }
  462. static const VMStateDescription vmstate_piix3_rcr = {
  463. .name = "PIIX3/rcr",
  464. .version_id = 1,
  465. .minimum_version_id = 1,
  466. .fields = (VMStateField []) {
  467. VMSTATE_UINT8(rcr, PIIX3State),
  468. VMSTATE_END_OF_LIST()
  469. }
  470. };
  471. static const VMStateDescription vmstate_piix3 = {
  472. .name = "PIIX3",
  473. .version_id = 3,
  474. .minimum_version_id = 2,
  475. .minimum_version_id_old = 2,
  476. .post_load = piix3_post_load,
  477. .pre_save = piix3_pre_save,
  478. .fields = (VMStateField[]) {
  479. VMSTATE_PCI_DEVICE(dev, PIIX3State),
  480. VMSTATE_INT32_ARRAY_V(pci_irq_levels_vmstate, PIIX3State,
  481. PIIX_NUM_PIRQS, 3),
  482. VMSTATE_END_OF_LIST()
  483. },
  484. .subsections = (VMStateSubsection[]) {
  485. {
  486. .vmsd = &vmstate_piix3_rcr,
  487. .needed = piix3_rcr_needed,
  488. },
  489. { 0 }
  490. }
  491. };
  492. static void rcr_write(void *opaque, hwaddr addr, uint64_t val, unsigned len)
  493. {
  494. PIIX3State *d = opaque;
  495. if (val & 4) {
  496. qemu_system_reset_request();
  497. return;
  498. }
  499. d->rcr = val & 2; /* keep System Reset type only */
  500. }
  501. static uint64_t rcr_read(void *opaque, hwaddr addr, unsigned len)
  502. {
  503. PIIX3State *d = opaque;
  504. return d->rcr;
  505. }
  506. static const MemoryRegionOps rcr_ops = {
  507. .read = rcr_read,
  508. .write = rcr_write,
  509. .endianness = DEVICE_LITTLE_ENDIAN
  510. };
  511. static int piix3_initfn(PCIDevice *dev)
  512. {
  513. PIIX3State *d = DO_UPCAST(PIIX3State, dev, dev);
  514. isa_bus_new(DEVICE(d), pci_address_space_io(dev));
  515. memory_region_init_io(&d->rcr_mem, OBJECT(dev), &rcr_ops, d,
  516. "piix3-reset-control", 1);
  517. memory_region_add_subregion_overlap(pci_address_space_io(dev), RCR_IOPORT,
  518. &d->rcr_mem, 1);
  519. qemu_register_reset(piix3_reset, d);
  520. return 0;
  521. }
  522. static void piix3_class_init(ObjectClass *klass, void *data)
  523. {
  524. DeviceClass *dc = DEVICE_CLASS(klass);
  525. PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
  526. dc->desc = "ISA bridge";
  527. dc->vmsd = &vmstate_piix3;
  528. dc->hotpluggable = false;
  529. k->init = piix3_initfn;
  530. k->config_write = piix3_write_config;
  531. k->vendor_id = PCI_VENDOR_ID_INTEL;
  532. /* 82371SB PIIX3 PCI-to-ISA bridge (Step A1) */
  533. k->device_id = PCI_DEVICE_ID_INTEL_82371SB_0;
  534. k->class_id = PCI_CLASS_BRIDGE_ISA;
  535. /*
  536. * Reason: part of PIIX3 southbridge, needs to be wired up by
  537. * pc_piix.c's pc_init1()
  538. */
  539. dc->cannot_instantiate_with_device_add_yet = true;
  540. }
  541. static const TypeInfo piix3_info = {
  542. .name = "PIIX3",
  543. .parent = TYPE_PCI_DEVICE,
  544. .instance_size = sizeof(PIIX3State),
  545. .class_init = piix3_class_init,
  546. };
  547. static void piix3_xen_class_init(ObjectClass *klass, void *data)
  548. {
  549. DeviceClass *dc = DEVICE_CLASS(klass);
  550. PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
  551. dc->desc = "ISA bridge";
  552. dc->vmsd = &vmstate_piix3;
  553. dc->hotpluggable = false;
  554. k->init = piix3_initfn;
  555. k->config_write = piix3_write_config_xen;
  556. k->vendor_id = PCI_VENDOR_ID_INTEL;
  557. /* 82371SB PIIX3 PCI-to-ISA bridge (Step A1) */
  558. k->device_id = PCI_DEVICE_ID_INTEL_82371SB_0;
  559. k->class_id = PCI_CLASS_BRIDGE_ISA;
  560. /*
  561. * Reason: part of PIIX3 southbridge, needs to be wired up by
  562. * pc_piix.c's pc_init1()
  563. */
  564. dc->cannot_instantiate_with_device_add_yet = true;
  565. };
  566. static const TypeInfo piix3_xen_info = {
  567. .name = "PIIX3-xen",
  568. .parent = TYPE_PCI_DEVICE,
  569. .instance_size = sizeof(PIIX3State),
  570. .class_init = piix3_xen_class_init,
  571. };
  572. static void i440fx_class_init(ObjectClass *klass, void *data)
  573. {
  574. DeviceClass *dc = DEVICE_CLASS(klass);
  575. PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
  576. k->init = i440fx_initfn;
  577. k->config_write = i440fx_write_config;
  578. k->vendor_id = PCI_VENDOR_ID_INTEL;
  579. k->device_id = PCI_DEVICE_ID_INTEL_82441;
  580. k->revision = 0x02;
  581. k->class_id = PCI_CLASS_BRIDGE_HOST;
  582. dc->desc = "Host bridge";
  583. dc->vmsd = &vmstate_i440fx;
  584. /*
  585. * PCI-facing part of the host bridge, not usable without the
  586. * host-facing part, which can't be device_add'ed, yet.
  587. */
  588. dc->cannot_instantiate_with_device_add_yet = true;
  589. dc->hotpluggable = false;
  590. }
  591. static const TypeInfo i440fx_info = {
  592. .name = TYPE_I440FX_PCI_DEVICE,
  593. .parent = TYPE_PCI_DEVICE,
  594. .instance_size = sizeof(PCII440FXState),
  595. .class_init = i440fx_class_init,
  596. };
  597. static const char *i440fx_pcihost_root_bus_path(PCIHostState *host_bridge,
  598. PCIBus *rootbus)
  599. {
  600. I440FXState *s = I440FX_PCI_HOST_BRIDGE(host_bridge);
  601. /* For backwards compat with old device paths */
  602. if (s->short_root_bus) {
  603. return "0000";
  604. }
  605. return "0000:00";
  606. }
  607. static Property i440fx_props[] = {
  608. DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, I440FXState,
  609. pci_hole64_size, DEFAULT_PCI_HOLE64_SIZE),
  610. DEFINE_PROP_UINT32("short_root_bus", I440FXState, short_root_bus, 0),
  611. DEFINE_PROP_END_OF_LIST(),
  612. };
  613. static void i440fx_pcihost_class_init(ObjectClass *klass, void *data)
  614. {
  615. DeviceClass *dc = DEVICE_CLASS(klass);
  616. PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass);
  617. hc->root_bus_path = i440fx_pcihost_root_bus_path;
  618. dc->realize = i440fx_pcihost_realize;
  619. dc->fw_name = "pci";
  620. dc->props = i440fx_props;
  621. }
  622. static const TypeInfo i440fx_pcihost_info = {
  623. .name = TYPE_I440FX_PCI_HOST_BRIDGE,
  624. .parent = TYPE_PCI_HOST_BRIDGE,
  625. .instance_size = sizeof(I440FXState),
  626. .instance_init = i440fx_pcihost_initfn,
  627. .class_init = i440fx_pcihost_class_init,
  628. };
  629. static void i440fx_register_types(void)
  630. {
  631. type_register_static(&i440fx_info);
  632. type_register_static(&piix3_info);
  633. type_register_static(&piix3_xen_info);
  634. type_register_static(&i440fx_pcihost_info);
  635. }
  636. type_init(i440fx_register_types)