2 * This file is part of the Palacios Virtual Machine Monitor developed
3 * by the V3VEE Project with funding from the United States National
4 * Science Foundation and the Department of Energy.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2009, Lei Xia <lxia@northwestern.edu>
11 * Copyright (c) 2009, Chang Seok Bae <jhuell@gmail.com>
12 * Copyright (c) 2009, Jack Lange <jarusl@cs.northwestern.edu>
13 * Copyright (c) 2009, The V3VEE Project <http://www.v3vee.org>
14 * All rights reserved.
16 * Author: Lei Xia <lxia@northwestern.edu>
17 * Chang Seok Bae <jhuell@gmail.com>
18 * Jack Lange <jarusl@cs.northwestern.edu>
20 * This is free software. You are permitted to use,
21 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
24 #include <devices/piix3.h>
25 #include <palacios/vmm.h>
26 #include <devices/pci.h>
27 #include <devices/southbridge.h>
31 static int reset_piix3(struct vm_device * dev) {
32 struct v3_southbridge * piix3 = (struct v3_southbridge *)(dev->private_data);
33 struct pci_device * pci_dev = piix3->southbridge_pci;
35 pci_dev->config_header.command = 0x0007; // master, memory and I/O
36 pci_dev->config_header.status = 0x0200;
38 pci_dev->config_space[0x4c] = 0x4d;
39 pci_dev->config_space[0x4e] = 0x03;
40 pci_dev->config_space[0x4f] = 0x00;
41 pci_dev->config_space[0x60] = 0x80;
42 pci_dev->config_space[0x69] = 0x02;
43 pci_dev->config_space[0x70] = 0x80;
44 pci_dev->config_space[0x76] = 0x0c;
45 pci_dev->config_space[0x77] = 0x0c;
46 pci_dev->config_space[0x78] = 0x02;
47 pci_dev->config_space[0x79] = 0x00;
48 pci_dev->config_space[0x80] = 0x00;
49 pci_dev->config_space[0x82] = 0x00;
50 pci_dev->config_space[0xa0] = 0x08;
51 pci_dev->config_space[0xa2] = 0x00;
52 pci_dev->config_space[0xa3] = 0x00;
53 pci_dev->config_space[0xa4] = 0x00;
54 pci_dev->config_space[0xa5] = 0x00;
55 pci_dev->config_space[0xa6] = 0x00;
56 pci_dev->config_space[0xa7] = 0x00;
57 pci_dev->config_space[0xa8] = 0x0f;
58 pci_dev->config_space[0xaa] = 0x00;
59 pci_dev->config_space[0xab] = 0x00;
60 pci_dev->config_space[0xac] = 0x00;
61 pci_dev->config_space[0xae] = 0x00;
67 static int init_piix3(struct vm_device * dev) {
68 struct v3_southbridge * piix3 = (struct v3_southbridge *)(dev->private_data);
69 struct pci_device * pci_dev = NULL;
70 struct v3_pci_bar bars[6];
73 for (i = 0; i < 6; i++) {
74 bars[i].type = PCI_BAR_NONE;
77 pci_dev = v3_pci_register_device(piix3->pci_bus, PCI_MULTIFUNCTION,
80 NULL, NULL, NULL, dev);
82 PrintError("Could not register PCI Device for PIIX3\n");
86 pci_dev->config_header.vendor_id = 0x8086;
87 pci_dev->config_header.device_id = 0x7000; // PIIX4 is 0x7001
88 pci_dev->config_header.subclass = 0x01; // SubClass: host2pci
89 pci_dev->config_header.class = 0x06; // Class: PCI bridge
91 piix3->southbridge_pci = pci_dev;
99 static int deinit_piix3(struct vm_device * dev) {
104 static struct vm_device_ops dev_ops = {
106 .deinit = deinit_piix3,
107 .reset = reset_piix3,
113 struct vm_device * v3_create_piix3(struct vm_device * pci) {
114 struct v3_southbridge * piix3 = (struct v3_southbridge *)V3_Malloc(sizeof(struct v3_southbridge));
115 struct vm_device * dev = NULL;
117 piix3->pci_bus = pci;
118 piix3->type = V3_SB_PIIX3;
120 dev = v3_create_device("PIIX3", &dev_ops, piix3);
122 PrintDebug("Created PIIX3\n");