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".
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;
70 static int piix_free(struct vm_device * dev) {
75 static struct v3_device_ops dev_ops = {
85 static int setup_pci(struct vm_device * dev) {
86 struct v3_southbridge * piix3 = (struct v3_southbridge *)(dev->private_data);
87 struct pci_device * pci_dev = NULL;
88 struct v3_pci_bar bars[6];
91 for (i = 0; i < 6; i++) {
92 bars[i].type = PCI_BAR_NONE;
95 pci_dev = v3_pci_register_device(piix3->pci_bus, PCI_MULTIFUNCTION,
98 NULL, NULL, NULL, dev);
99 if (pci_dev == NULL) {
100 PrintError("Could not register PCI Device for PIIX3\n");
104 pci_dev->config_header.vendor_id = 0x8086;
105 pci_dev->config_header.device_id = 0x7000; // PIIX4 is 0x7001
106 pci_dev->config_header.class = PCI_CLASS_BRIDGE;
107 pci_dev->config_header.subclass = PCI_BRIDGE_SUBCLASS_PCI_ISA;
109 piix3->southbridge_pci = pci_dev;
116 static int piix3_init(struct guest_info * vm, void * cfg_data) {
117 struct v3_southbridge * piix3 = (struct v3_southbridge *)V3_Malloc(sizeof(struct v3_southbridge));
118 struct vm_device * dev = NULL;
119 struct vm_device * pci = v3_find_dev(vm, (char *)cfg_data);
122 PrintError("Could not find PCI device\n");
126 piix3->pci_bus = pci;
127 piix3->type = V3_SB_PIIX3;
129 dev = v3_allocate_device("PIIX3", &dev_ops, piix3);
131 if (v3_attach_device(vm, dev) == -1) {
132 PrintError("Could not attach device %s\n", "PIIX3");
136 PrintDebug("Created PIIX3\n");
138 return setup_pci(dev);
142 device_register("PIIX3", piix3_init)