Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Cleanup and sanity-checking of use of strncpy/strcpy (Coverity static analysis)
[palacios.git] / palacios / src / devices / pci.c
1 /* 
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.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2009, Jack Lange <jarusl@cs.northwestern.edu>
11  * Copyright (c) 2009, Lei Xia <lxia@northwestern.edu>
12  * Copyright (c) 2009, Chang Seok Bae <jhuell@gmail.com>
13  * Copyright (c) 2009, The V3VEE Project <http://www.v3vee.org> 
14  * All rights reserved.
15  *
16  * Author:  Jack Lange <jarusl@cs.northwestern.edu>
17  *          Lei Xia <lxia@northwestern.edu>
18  *          Chang Seok Bae <jhuell@gmail.com>
19  *
20  * This is free software.  You are permitted to use,
21  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
22  */ 
23  
24  
25
26 #include <palacios/vmm.h>
27 #include <palacios/vmm_types.h>
28 #include <palacios/vmm_io.h>
29 #include <palacios/vmm_intr.h>
30 #include <palacios/vmm_rbtree.h>
31 #include <palacios/vmm_dev_mgr.h>
32
33 #include <devices/pci.h>
34 #include <devices/pci_types.h>
35
36 #include <palacios/vm_guest.h>
37 #include <palacios/vm_guest_mem.h>
38
39
40 #include <devices/apic.h>
41
42
43 #ifndef V3_CONFIG_DEBUG_PCI
44 #undef PrintDebug
45 #define PrintDebug(fmt, args...)
46 #endif
47
48
49 #define CONFIG_ADDR_PORT    0x0cf8
50 #define CONFIG_DATA_PORT    0x0cfc
51
52 #define PCI_DEV_IO_PORT_BASE 0xc000
53
54 #define PCI_BUS_COUNT 1
55
56 // This must always be a multiple of 8
57 #define MAX_BUS_DEVICES 32
58
59 #define PCI_CAP_ID_MSI 0x05
60 #define PCI_CAP_ID_MSIX 0x11
61
62
63 struct pci_addr_reg {
64     union {
65         uint32_t val;
66         struct {
67             uint_t rsvd       : 2;
68             uint_t reg_num    : 6;
69             uint_t fn_num     : 3;
70             uint_t dev_num    : 5;
71             uint_t bus_num    : 8;
72             uint_t hi_reg_num : 4;
73             uint_t rsvd2      : 3;
74             uint_t enable     : 1;
75         } __attribute__((packed));
76     } __attribute__((packed));
77 } __attribute__((packed));
78
79
80
81
82
83 struct pci_bus {
84     int bus_num;
85
86     // Red Black tree containing all attached devices
87     struct rb_root devices;
88
89     // Bitmap of the allocated device numbers
90     uint8_t dev_map[MAX_BUS_DEVICES / 8];
91
92
93     int (*raise_pci_irq)(struct pci_device * pci_dev, void * dev_data, struct v3_irq * vec);
94     int (*lower_pci_irq)(struct pci_device * pci_dev, void * dev_data, struct v3_irq * vec);
95     void * irq_dev_data;
96 };
97
98
99
100 struct pci_internal {
101     // Configuration address register
102     struct pci_addr_reg addr_reg;
103
104     // Base IO Port which PCI devices will register with...
105     uint16_t dev_io_base; 
106
107     // Attached Busses
108     struct pci_bus bus_list[PCI_BUS_COUNT];
109 };
110
111
112
113 struct cfg_range_hook {
114     uint32_t start;
115     uint32_t length;
116
117     int (*write)(struct pci_device * pci_dev, uint32_t offset, 
118                  void * src, uint_t length, void * private_data);
119
120     int (*read)(struct pci_device * pci_dev, uint32_t offset, 
121                 void * dst, uint_t length, void * private_data);
122
123     void * private_data;
124
125     struct list_head list_node;
126 };
127
128
129
130 struct pci_cap {
131     uint8_t id;
132     uint32_t offset;
133     uint8_t enabled;
134
135     struct list_head cap_node;
136 };
137
138
139 // These mark read only fields in the pci config header. 
140 // If a bit is 1, then the field is writable in the header
141 /* Notes: 
142  * BIST is disabled by default (All writes to it will be dropped 
143  * Cardbus CIS is disabled (All writes are dropped)
144  * Writes to capability pointer are disabled
145  */
146 static uint8_t pci_hdr_write_mask_00[64] = { 0x00, 0x00, 0x00, 0x00, /* Device ID, Vendor ID */
147                                              0xbf, 0xff, 0x00, 0xf9, /* Command, status */
148                                              0x00, 0x00, 0x00, 0x00, /* Revision ID, Class code */
149                                              0x00, 0xff, 0x00, 0x00, /* CacheLine Size, Latency Timer, Header Type, BIST */
150                                              0xff, 0xff, 0xff, 0xff, /* BAR 0 */
151                                              0xff, 0xff, 0xff, 0xff, /* BAR 1 */
152                                              0xff, 0xff, 0xff, 0xff, /* BAR 2 */
153                                              0xff, 0xff, 0xff, 0xff, /* BAR 3 */
154                                              0xff, 0xff, 0xff, 0xff, /* BAR 4 */
155                                              0xff, 0xff, 0xff, 0xff, /* BAR 5 */
156                                              0x00, 0x00, 0x00, 0x00, /* CardBus CIS Ptr */
157                                              0xff, 0xff, 0xff, 0xff, /* SubSystem Vendor ID, SubSystem ID */
158                                              0xff, 0xff, 0xff, 0xff, /* ExpRom BAR */
159                                              0x00, 0x00, 0x00, 0x00, /* CAP ptr (0xfc to enable), RSVD */
160                                              0x00, 0x00, 0x00, 0x00, /* Reserved */
161                                              0xff, 0x00, 0x00, 0x00 /* INTR Line, INTR Pin, MIN_GNT, MAX_LAT */
162 }; 
163
164
165
166
167 #ifdef V3_CONFIG_DEBUG_PCI
168
169 static void pci_dump_state(struct pci_internal * pci_state) {
170     struct rb_node * node = v3_rb_first(&(pci_state->bus_list[0].devices));
171     struct pci_device * tmp_dev = NULL;
172     
173     PrintDebug(VM_NONE, VCORE_NONE, "===PCI: Dumping state Begin ==========\n");
174     
175     do {
176         tmp_dev = rb_entry(node, struct pci_device, dev_tree_node);
177
178         PrintDebug(VM_NONE, VCORE_NONE, "PCI Device Number: %d (%s):\n", tmp_dev->dev_num,  tmp_dev->name);
179         PrintDebug(VM_NONE, VCORE_NONE, "irq = %d\n", tmp_dev->config_header.intr_line);
180         PrintDebug(VM_NONE, VCORE_NONE, "Vend ID: 0x%x\n", tmp_dev->config_header.vendor_id);
181         PrintDebug(VM_NONE, VCORE_NONE, "Device ID: 0x%x\n", tmp_dev->config_header.device_id);
182
183     } while ((node = v3_rb_next(node)));
184     
185     PrintDebug(VM_NONE, VCORE_NONE, "====PCI: Dumping state End==========\n");
186 }
187
188 #endif
189
190
191
192
193 // Scan the dev_map bitmap for the first '0' bit
194 static int get_free_dev_num(struct pci_bus * bus) {
195     int i, j;
196
197     for (i = 0; i < sizeof(bus->dev_map); i++) {
198         PrintDebug(VM_NONE, VCORE_NONE, "i=%d\n", i);
199         if (bus->dev_map[i] != 0xff) {
200             // availability
201             for (j = 0; j < 8; j++) {
202                 PrintDebug(VM_NONE, VCORE_NONE, "\tj=%d\n", j);
203                 if (!(bus->dev_map[i] & (0x1 << j))) {
204                     return ((i * 8) + j);
205                 }
206             }
207         }
208     }
209
210     return -1;
211 }
212
213 static void allocate_dev_num(struct pci_bus * bus, int dev_num) {
214     int major = (dev_num / 8);
215     int minor = dev_num % 8;
216
217     bus->dev_map[major] |= (0x1 << minor);
218 }
219
220
221
222 static inline 
223 struct pci_device * __add_device_to_bus(struct pci_bus * bus, struct pci_device * dev) {
224
225   struct rb_node ** p = &(bus->devices.rb_node);
226   struct rb_node * parent = NULL;
227   struct pci_device * tmp_dev = NULL;
228
229   while (*p) {
230     parent = *p;
231     tmp_dev = rb_entry(parent, struct pci_device, dev_tree_node);
232
233     if (dev->devfn < tmp_dev->devfn) {
234       p = &(*p)->rb_left;
235     } else if (dev->devfn > tmp_dev->devfn) {
236       p = &(*p)->rb_right;
237     } else {
238       return tmp_dev;
239     }
240   }
241
242   rb_link_node(&(dev->dev_tree_node), parent, p);
243
244   return NULL;
245 }
246
247
248 static inline 
249 struct pci_device * add_device_to_bus(struct pci_bus * bus, struct pci_device * dev) {
250
251   struct pci_device * ret = NULL;
252
253   if ((ret = __add_device_to_bus(bus, dev))) {
254     return ret;
255   }
256
257   v3_rb_insert_color(&(dev->dev_tree_node), &(bus->devices));
258
259   allocate_dev_num(bus, dev->dev_num);
260
261   return NULL;
262 }
263
264
265 static struct pci_device * get_device(struct pci_bus * bus, uint8_t dev_num, uint8_t fn_num) {
266     struct rb_node * n = bus->devices.rb_node;
267     struct pci_device * dev = NULL;
268     uint8_t devfn = ((dev_num & 0x1f) << 3) | (fn_num & 0x7);
269
270     while (n) {
271         dev = rb_entry(n, struct pci_device, dev_tree_node);
272         
273         if (devfn < dev->devfn) {
274             n = n->rb_left;
275         } else if (devfn > dev->devfn) {
276             n = n->rb_right;
277         } else {
278             return dev;
279         }
280     }
281     
282     return NULL;
283 }
284
285
286
287
288 // There won't be many hooks at all, so unordered lists are acceptible for now 
289 static struct cfg_range_hook * find_cfg_range_hook(struct pci_device * pci, uint32_t start, uint32_t length) {
290     uint32_t end = start + length - 1; // end is inclusive
291     struct cfg_range_hook * hook = NULL;
292
293     list_for_each_entry(hook, &(pci->cfg_hooks), list_node) {
294         uint32_t hook_end = hook->start + hook->length - 1;
295         if (!((hook->start > end) || (hook_end < start))) {
296             return hook;
297         }
298     }
299     
300     return NULL;
301 }
302
303
304 int v3_pci_hook_config_range(struct pci_device * pci, 
305                              uint32_t start, uint32_t length, 
306                              int (*write)(struct pci_device * pci_dev, uint32_t offset, 
307                                                  void * src, uint_t length, void * private_data), 
308                              int (*read)(struct pci_device * pci_dev, uint32_t offset, 
309                                                 void * dst, uint_t length, void * private_data), 
310                              void * private_data) {
311     struct cfg_range_hook * hook = NULL;    
312     
313
314     if (find_cfg_range_hook(pci, start, length)) {
315         PrintError(VM_NONE, VCORE_NONE, "Tried to hook an already hooked config region\n");
316         return -1;
317     }
318     
319     hook = V3_Malloc(sizeof(struct cfg_range_hook));
320
321     if (!hook) {
322         PrintError(VM_NONE, VCORE_NONE, "Could not allocate range hook\n");
323         return -1;
324     }
325
326     memset(hook, 0, sizeof(struct cfg_range_hook));
327
328     hook->start = start;
329     hook->length = length;
330     hook->private_data = private_data;
331     hook->write = write;
332     hook->read = read;
333
334     list_add(&(hook->list_node), &(pci->cfg_hooks));
335
336     return 0;
337
338 }
339
340
341
342
343 // Note byte ordering: LSB -> MSB
344 static uint8_t msi_32_rw_bitmask[10] = { 0x00, 0x00,                     /* ID, next ptr */
345                                          0x71, 0x00,                     /* MSG CTRL */
346                                          0xfc, 0xff, 0xff, 0xff,         /* MSG ADDR */
347                                          0xff, 0xff};                    /* MSG DATA */
348
349 static uint8_t msi_64_rw_bitmask[14] = { 0x00, 0x00,                     /* ID, next ptr */
350                                          0x71, 0x00,                     /* MSG CTRL */
351                                          0xfc, 0xff, 0xff, 0xff,         /* MSG LO ADDR */
352                                          0xff, 0xff, 0xff, 0xff,         /* MSG HI ADDR */
353                                          0xff, 0xff};                    /* MSG DATA */
354
355 static uint8_t msi_64pervect_rw_bitmask[24] = { 0x00, 0x00,              /* ID, next ptr */
356                                                 0x71, 0x00,              /* MSG CTRL */
357                                                 0xfc, 0xff, 0xff, 0xff,  /* MSG LO CTRL */
358                                                 0xff, 0xff, 0xff, 0xff,  /* MSG HI ADDR */
359                                                 0xff, 0xff,              /* MSG DATA */
360                                                 0x00, 0x00,              /* RSVD */
361                                                 0xff, 0xff, 0xff, 0xff,  
362                                                 0x00, 0x00, 0x00, 0x00}; 
363
364 static uint8_t msix_rw_bitmask[12] = { 0x00, 0x00,                       /* ID, next ptr */
365                                        0x00, 0x80, 
366                                        0xff, 0xff, 0xff, 0xff,
367                                        0x08, 0xff, 0xff, 0xff};
368
369
370 /* I am completely guessing what the format is here. 
371    I only have version 1 of the PCIe spec and cannot download version 2 or 3 
372    without paying the PCI-SIG $3000 a year for membership. 
373    So this is just cobbled together from the version 1 spec and KVM. 
374 */ 
375
376
377 static uint8_t pciev1_rw_bitmask[20] = { 0x00, 0x00, /* ID, next ptr */
378                                          0x00, 0x00, /* PCIE CAP register */
379                                          0x00, 0x00, 0x00, 0x00, /* DEV CAP */
380                                          0xff, 0xff, /* DEV CTRL */
381                                          0x0f, 0x00, /* DEV STATUS */
382                                          0x00, 0x00, 0x00, 0x00, /* LINK CAP */
383                                          0xfb, 0x01, /* LINK CTRL */
384                                          0x00, 0x00  /* LINK STATUS */ 
385 };
386
387
388 static uint8_t pciev2_rw_bitmask[60] = { 0x00, 0x00, /* ID, next ptr */
389                                          0x00, 0x00, /* PCIE CAP register */
390                                          0x00, 0x00, 0x00, 0x00, /* DEV CAP */
391                                          0xff, 0xff, /* DEV CTRL */
392                                          0x0f, 0x00, /* DEV STATUS */
393                                          0x00, 0x00, 0x00, 0x00, /* LINK CAP */
394                                          0xfb, 0x01, /* LINK CTRL */
395                                          0x00, 0x00, /* LINK STATUS */ 
396                                          0x00, 0x00, 0x00, 0x00, /* SLOT CAP ?? */
397                                          0x00, 0x00, /* SLOT CTRL ?? */
398                                          0x00, 0x00, /* SLOT STATUS */
399                                          0x00, 0x00, /* ROOT CTRL */
400                                          0x00, 0x00, /* ROOT CAP */
401                                          0x00, 0x00, 0x00, 0x00, /* ROOT STATUS */
402                                          0x00, 0x00, 0x00, 0x00, /* WHO THE FUCK KNOWS */
403                                          0x00, 0x00, 0x00, 0x00, 
404                                          0x00, 0x00, 0x00, 0x00, 
405                                          0x00, 0x00, 0x00, 0x00, 
406                                          0x00, 0x00, 0x00, 0x00 
407 };
408
409 static uint8_t pm_rw_bitmask[] = { 0x00, 0x00, /* ID, next ptr */
410                                    0x00, 0x00, /* PWR MGMT CAPS */
411                                    0x03, 0x9f, /* PWR MGMT CTRL */
412                                    0x00, 0x00  /* PMCSR_BSE, Data */
413 };
414
415
416
417 int cap_write(struct pci_device * pci, uint32_t offset, void * src, uint_t length, void * private_data) {
418     struct pci_cap * cap = private_data;
419     uint32_t cap_offset = cap->offset;
420     pci_cap_type_t cap_type = cap->id;
421
422     uint32_t write_offset = offset - cap_offset;
423     void * cap_ptr = &(pci->config_space[cap_offset + 2]);    
424     int i = 0;
425
426     int msi_was_enabled = 0;
427     int msix_was_enabled = 0;
428
429
430     V3_Print(VM_NONE, VCORE_NONE, "CAP write trapped (val=%x, cfg_offset=%d, write_offset=%d)\n", *(uint32_t *)src, offset, write_offset);
431
432     if (cap_type == PCI_CAP_MSI) {
433         struct msi_msg_ctrl * msg_ctrl = cap_ptr;
434
435         if (msg_ctrl->msi_enable == 1) {
436             msi_was_enabled = 1;
437         }
438     } else if (cap_type == PCI_CAP_MSIX) {
439         struct msix_cap * msix_cap = cap_ptr;
440
441         if (msix_cap->msg_ctrl.msix_enable == 1) {
442             msix_was_enabled = 1;
443         }
444     }
445
446     for (i = 0; i < length; i++) {
447         uint8_t mask = 0;
448
449         if (cap_type == PCI_CAP_MSI) {
450             struct msi_msg_ctrl * msg_ctrl = cap_ptr;
451
452             V3_Print(VM_NONE, VCORE_NONE, "MSI Cap Ctrl=%x\n", *(uint16_t *)pci->msi_cap);
453             V3_Print(VM_NONE, VCORE_NONE, "MSI ADDR=%x\n", *(uint32_t *)(cap_ptr + 2));
454             V3_Print(VM_NONE, VCORE_NONE, "MSI HI ADDR=%x\n", *(uint32_t *)(cap_ptr + 6));
455             V3_Print(VM_NONE, VCORE_NONE, "MSI Data=%x\n", *(uint16_t *)(cap_ptr + 10));
456
457             if (msg_ctrl->cap_64bit) {
458                 if (msg_ctrl->per_vect_mask) {
459                     mask = msi_64pervect_rw_bitmask[write_offset];
460                 } else {
461                     mask = msi_64_rw_bitmask[write_offset];
462                 }
463             } else {
464                 mask = msi_32_rw_bitmask[write_offset];
465             }
466         } else if (cap_type == PCI_CAP_MSIX) {
467             mask = msix_rw_bitmask[write_offset];
468         } else if (cap_type == PCI_CAP_PCIE) {
469             struct pcie_cap_reg * pcie_cap = cap_ptr;
470
471             if (pcie_cap->version == 1) {
472                 mask = pciev1_rw_bitmask[write_offset];
473             } else if (pcie_cap->version == 2) {
474                 mask = pciev2_rw_bitmask[write_offset];
475             } else {
476                 return 0;
477             }
478         } else if (cap_type == PCI_CAP_PM) {
479             mask = pm_rw_bitmask[write_offset];
480         }
481
482         pci->config_space[offset + i] &= ~mask;
483         pci->config_space[offset + i] |= ((*(uint8_t *)(src + i)) & mask);
484
485         write_offset++;
486     }
487
488
489     if (pci->cmd_update) {
490
491         /* Detect changes to interrupt types for cmd updates */
492         if (cap_type == PCI_CAP_MSI) {
493             struct msi_msg_ctrl * msg_ctrl = cap_ptr;
494             
495             V3_Print(VM_NONE, VCORE_NONE, "msi_was_enabled=%d, msi_is_enabled=%d\n", msi_was_enabled,  msg_ctrl->msi_enable);
496
497             if ((msg_ctrl->msi_enable == 1) && (msi_was_enabled == 0)) {
498                 pci->irq_type = IRQ_MSI;
499                 pci->cmd_update(pci, PCI_CMD_MSI_ENABLE, msg_ctrl->mult_msg_enable, pci->priv_data);
500             } else if ((msg_ctrl->msi_enable == 0) && (msi_was_enabled == 1)) {
501                 pci->irq_type = IRQ_NONE;
502                 pci->cmd_update(pci, PCI_CMD_MSI_DISABLE, 0, pci->priv_data);
503             }
504         } else if (cap_type == PCI_CAP_MSIX) {
505             struct msix_cap * msix_cap = cap_ptr;
506
507             if ((msix_cap->msg_ctrl.msix_enable == 1) && (msix_was_enabled == 0)) {
508                 pci->irq_type = IRQ_MSIX;
509                 pci->cmd_update(pci, PCI_CMD_MSIX_ENABLE, msix_cap->msg_ctrl.table_size, pci->priv_data);
510             } else if ((msix_cap->msg_ctrl.msix_enable == 0) && (msix_was_enabled == 1)) {
511                 pci->irq_type = IRQ_NONE;
512                 pci->cmd_update(pci, PCI_CMD_MSIX_DISABLE, msix_cap->msg_ctrl.table_size, pci->priv_data);
513             }
514         }
515     }
516
517     return 0;
518 }
519
520
521 static int init_pci_cap(struct pci_device * pci, pci_cap_type_t cap_type, uint_t cap_offset) {
522     void * cap_ptr = &(pci->config_space[cap_offset + 2]);
523
524     if (cap_type == PCI_CAP_MSI) {
525         struct msi32_msg_addr * msi = cap_ptr;
526
527         // We only expose a basic 32 bit MSI interface
528         msi->msg_ctrl.msi_enable = 0;
529         msi->msg_ctrl.mult_msg_enable = 0;
530         msi->msg_ctrl.cap_64bit = 0;
531         msi->msg_ctrl.per_vect_mask = 0;
532         
533         msi->addr.val = 0; 
534         msi->data.val = 0;
535
536     } else if (cap_type == PCI_CAP_MSIX) {
537         
538         
539
540     } else if (cap_type == PCI_CAP_PCIE) {
541         struct pcie_cap_v2 * pcie = cap_ptr;
542         
543         // The v1 and v2 formats are identical for the first X bytes
544         // So we use the v2 struct, and only modify extended fields if v2 is detected
545         
546         pcie->dev_cap.fn_level_reset = 0;
547         
548         pcie->dev_ctrl.val &= 0x70e0; // only preserve max_payload_size and max_read_req_size untouched
549         pcie->dev_ctrl.relaxed_order_enable = 1;
550         pcie->dev_ctrl.no_snoop_enable = 1;
551
552         pcie->dev_status.val = 0;
553
554         pcie->link_cap.val &= 0x0003ffff;
555
556         pcie->link_status.val &= 0x03ff;
557         
558         if (pcie->pcie_cap.version >= 2) {
559             pcie->slot_cap = 0;
560             pcie->slot_ctrl = 0;
561             pcie->slot_status = 0;
562
563             pcie->root_ctrl = 0;
564             pcie->root_cap = 0;
565             pcie->root_status = 0;
566         }
567     } else if (cap_type == PCI_CAP_PM) {
568
569     }
570
571
572     return 0;
573 }
574
575
576 // enumerate all capabilities and disable them.
577 static int scan_pci_caps(struct pci_device * pci) {
578     uint_t cap_offset = pci->config_header.cap_ptr;
579         
580     V3_Print(VM_NONE, VCORE_NONE, "Scanning for Capabilities (cap_offset=%d)\n", cap_offset);
581
582     while (cap_offset != 0) {
583         uint8_t id = pci->config_space[cap_offset];
584         uint8_t next = pci->config_space[cap_offset + 1];
585
586         V3_Print(VM_NONE, VCORE_NONE, "Found Capability 0x%x at offset %d (0x%x)\n", 
587                  id, cap_offset, cap_offset);
588
589         struct pci_cap * cap = V3_Malloc(sizeof(struct pci_cap));
590
591         if (!cap) {
592             PrintError(VM_NONE, VCORE_NONE, "Error allocating PCI CAP info\n");
593             return -1;
594         }
595         memset(cap, 0, sizeof(struct pci_cap));
596         
597         cap->id = id;
598         cap->offset = cap_offset;
599
600         list_add(&(cap->cap_node), &(pci->capabilities));
601
602         // set correct init values 
603         init_pci_cap(pci, id, cap_offset);
604
605
606         // set to the next pointer
607         cap_offset = next;
608     }
609
610     // Disable Capabilities
611     pci->config_header.cap_ptr = 0;
612
613     // Hook Cap pointer to return cached config space value
614     if (v3_pci_hook_config_range(pci, 0x34, 1, 
615                                  NULL, NULL, NULL) == -1) {
616         PrintError(VM_NONE, VCORE_NONE, "Could not hook cap pointer\n");
617         return -1;
618     }
619     
620
621
622 /*
623     // Disable all PCIE extended capabilities for now
624     pci->config_space[0x100] = 0;
625     pci->config_space[0x101] = 0;
626     pci->config_space[0x102] = 0;
627     pci->config_space[0x103] = 0;
628 */  
629
630
631     return 0;
632
633 }
634
635 int v3_pci_enable_capability(struct pci_device * pci, pci_cap_type_t cap_type) {
636     uint32_t size = 0;
637     struct pci_cap * tmp_cap = NULL;
638     struct pci_cap * cap = NULL;
639     void * cap_ptr = NULL;
640
641
642     list_for_each_entry(tmp_cap, &(pci->capabilities), cap_node) {
643         if (tmp_cap->id == cap_type) {
644             cap = tmp_cap;
645             break;
646         }
647     }
648
649     if ((cap == NULL) || (cap->enabled)) {
650         return -1;
651     }
652
653
654     V3_Print(VM_NONE, VCORE_NONE, "Found Capability %x at %x (%d)\n", cap_type, cap->offset, cap->offset);
655
656     // found the capability
657
658     // mark it as enabled
659     cap->enabled = 1;
660
661     cap_ptr = &(pci->config_space[cap->offset + 2]);
662
663     if (cap_type == PCI_CAP_MSI) {
664         pci->msi_cap = cap_ptr;
665         
666         if (pci->msi_cap->cap_64bit) {
667             if (pci->msi_cap->per_vect_mask) {
668                 // 64 bit MSI w/ per vector masking
669                 size = 22;
670             } else {
671                 // 64 bit MSI
672                 size = 12;
673             }
674         } else {
675             // 32 bit MSI
676             size = 8;
677         }
678     } else if (cap_type == PCI_CAP_MSIX) {
679         pci->msix_cap = cap_ptr;
680         
681         // disable passthrough for MSIX BAR
682
683         pci->bar[pci->msix_cap->bir].type = PCI_BAR_MEM32;
684
685         size = 10;
686     } else if (cap_type == PCI_CAP_PCIE) {
687         struct pcie_cap_reg * pcie_cap = (struct pcie_cap_reg *)&(pci->config_space[cap->offset + 2]);
688
689         if (pcie_cap->version == 1) {
690             size = 20;
691         } else if (pcie_cap->version == 2) {
692             size = 60;
693         } else {
694             return -1;
695         }
696     } else if (cap_type == PCI_CAP_PM) {
697         size = 8;
698     }
699
700
701     V3_Print(VM_NONE, VCORE_NONE, "Hooking capability range (offset=%d, size=%d)\n", cap->offset, size);
702
703     if (v3_pci_hook_config_range(pci, cap->offset, size + 2, 
704                                  cap_write, NULL, cap) == -1) {
705         PrintError(VM_NONE, VCORE_NONE, "Could not hook config range (start=%d, size=%d)\n", 
706                    cap->offset + 2, size);
707         return -1;
708     }
709
710
711
712     // link it to the active capabilities list
713     pci->config_space[cap->offset + 1] = pci->config_header.cap_ptr;
714     pci->config_header.cap_ptr = cap->offset; // add to the head of the list
715
716     return 0;
717 }
718
719
720
721
722 static int addr_port_read(struct guest_info * core, ushort_t port, void * dst, uint_t length, void * priv_data) {
723     struct pci_internal * pci_state = priv_data;
724     int reg_offset = port & 0x3;
725     uint8_t * reg_addr = ((uint8_t *)&(pci_state->addr_reg.val)) + reg_offset;
726
727     PrintDebug(core->vm_info, core, "Reading PCI Address Port (%x): %x len=%d\n", port, pci_state->addr_reg.val, length);
728
729     if (reg_offset + length > 4) {
730         PrintError(core->vm_info, core, "Invalid Address port write\n");
731         return -1;
732     }
733
734     memcpy(dst, reg_addr, length);    
735
736     return length;
737 }
738
739
740 static int addr_port_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
741     struct pci_internal * pci_state = priv_data;
742     int reg_offset = port & 0x3; 
743     uint8_t * reg_addr = ((uint8_t *)&(pci_state->addr_reg.val)) + reg_offset;
744
745     if (reg_offset + length > 4) {
746         PrintError(core->vm_info, core, "Invalid Address port write\n");
747         return -1;
748     }
749
750     // Set address register
751     memcpy(reg_addr, src, length);
752
753     PrintDebug(core->vm_info, core, "Writing PCI Address Port(%x): AddrReg=%x (op_val = %x, len=%d) \n", port, pci_state->addr_reg.val, *(uint32_t *)src, length);
754
755     return length;
756 }
757
758
759 static int data_port_read(struct guest_info * core, uint16_t port, void * dst, uint_t length, void * priv_data) {
760     struct pci_internal * pci_state =  priv_data;
761     struct pci_device * pci_dev = NULL;
762     uint_t reg_num =  (pci_state->addr_reg.hi_reg_num << 16) +(pci_state->addr_reg.reg_num << 2) + (port & 0x3);
763     int i = 0;
764     int bytes_left = length;
765
766     if (pci_state->addr_reg.bus_num != 0) {
767         memset(dst, 0xff, length);
768         return length;
769     }
770
771
772     pci_dev = get_device(&(pci_state->bus_list[0]), pci_state->addr_reg.dev_num, pci_state->addr_reg.fn_num);
773
774     
775     if (pci_dev == NULL) {
776         memset(dst, 0xff, length);
777         return length;
778     } 
779
780     PrintDebug(core->vm_info, core, "Reading PCI Data register. bus = %d, dev = %d, fn = %d, reg = %d (%x), cfg_reg = %x\n", 
781                pci_state->addr_reg.bus_num, 
782                pci_state->addr_reg.dev_num, 
783                pci_state->addr_reg.fn_num,
784                reg_num, reg_num, 
785                pci_state->addr_reg.val);
786
787
788     while (bytes_left > 0) {
789         struct cfg_range_hook * cfg_hook  = find_cfg_range_hook(pci_dev, reg_num + i, 1);
790         void * cfg_dst =  &(pci_dev->config_space[reg_num + i]);
791
792         if (cfg_hook) {
793             uint_t range_len = cfg_hook->length - ((reg_num + i) - cfg_hook->start);
794             range_len = (range_len > bytes_left) ? bytes_left : range_len;
795
796             if (cfg_hook->read) {
797                 cfg_hook->read(pci_dev, reg_num + i, cfg_dst, range_len, cfg_hook->private_data);
798             } else {
799             if (pci_dev->config_read) {
800                 if (pci_dev->config_read(pci_dev, reg_num + i, cfg_dst, range_len, pci_dev->priv_data) != 0) {
801                     PrintError(core->vm_info, core, "Error in config_read from PCI device (%s)\n", pci_dev->name);
802                 }
803             }
804         }
805             
806             bytes_left -= range_len;
807             i += range_len;
808         } else {
809             if (pci_dev->config_read) {
810             if (pci_dev->config_read(pci_dev, reg_num + i, cfg_dst, 1, pci_dev->priv_data) != 0) {
811                 PrintError(core->vm_info, core, "Error in config_read from PCI device (%s)\n", pci_dev->name);
812             }
813             }
814
815             bytes_left--;
816             i++;
817         } 
818     }       
819
820     memcpy(dst, &(pci_dev->config_space[reg_num]), length);
821             
822     PrintDebug(core->vm_info, core, "\tVal=%x, len=%d\n", *(uint32_t *)dst, length);
823
824     return length;
825 }
826
827
828
829 static int bar_update(struct pci_device * pci_dev, uint32_t offset, 
830                       void * src, uint_t length, void * private_data) {
831     struct v3_pci_bar * bar = (struct v3_pci_bar *)private_data;
832     int bar_offset = offset & ~0x03;
833     int bar_num = (bar_offset - 0x10) / 4;
834     uint32_t new_val = *(uint32_t *)src;
835     
836     PrintDebug(VM_NONE, VCORE_NONE, "Updating BAR Register  (Dev=%s) (bar=%d) (old_val=0x%x) (new_val=0x%x) (length=%d)\n", 
837                pci_dev->name, bar_num, bar->val, new_val, length);
838
839     // Cache the changes locally
840     memcpy(&(pci_dev->config_space[offset]), src, length);
841
842     if (bar->type == PCI_BAR_PASSTHROUGH) {
843         if (bar->bar_write(bar_num, (void *)(pci_dev->config_space + bar_offset), bar->private_data) == -1) {
844             PrintError(VM_NONE, VCORE_NONE, "Error in Passthrough bar write operation\n");
845             return -1;
846         }
847         
848         return 0;
849     }
850    
851     // Else we are a virtualized BAR
852
853     *(uint32_t *)(pci_dev->config_space + offset) &= bar->mask;
854
855     // Handle buggy code that discards the freaking I/O bit...
856     if (bar->type == PCI_BAR_IO && !(new_val & 0x1) ) {
857         PrintError(VM_NONE,VCORE_NONE,"Buggy guest:  Updating BAR %d of device %s discards the I/O bit...\n", bar_num, pci_dev->name);
858         *(uint32_t *)(pci_dev->config_space + offset) |= 0x1;
859         new_val |= 0x1;
860     }
861
862
863     // V3_Print(VM_NONE, VCORE_NONE,"mask=%x written val=%x\n", bar->mask, *(uint32_t *)(pci_dev->config_space + offset));
864
865     switch (bar->type) {
866         case PCI_BAR_IO: {
867             int i = 0;
868
869             PrintDebug(VM_NONE, VCORE_NONE, "\tRehooking %d IO ports from base 0x%x to 0x%x for %d ports\n",
870                        bar->num_ports, PCI_IO_BASE(bar->val), PCI_IO_BASE(new_val),
871                        bar->num_ports);
872
873             for (i = 0; i < bar->num_ports; i++) {
874
875                 PrintDebug(VM_NONE, VCORE_NONE, "Rehooking PCI IO port (old port=%u) (new port=%u)\n",  
876                            PCI_IO_BASE(bar->val) + i, PCI_IO_BASE(new_val) + i);
877
878                 v3_unhook_io_port(pci_dev->vm, PCI_IO_BASE(bar->val) + i);
879
880                 if (v3_hook_io_port(pci_dev->vm, PCI_IO_BASE(new_val) + i, 
881                                     bar->io_read, bar->io_write, 
882                                     bar->private_data) == -1) {
883
884                     PrintError(VM_NONE, VCORE_NONE, "Could not hook PCI IO port (old port=%u) (new port=%u)\n",  
885                                PCI_IO_BASE(bar->val) + i, PCI_IO_BASE(new_val) + i);
886                     //v3_print_io_map(pci_dev->vm);
887                     return -1;
888                 }
889             }
890
891             bar->val = new_val;
892
893             break;
894         }
895         case PCI_BAR_MEM32: {
896             v3_unhook_mem(pci_dev->vm, V3_MEM_CORE_ANY, (addr_t)(bar->val));
897             
898             if (bar->mem_read) {
899                 v3_hook_full_mem(pci_dev->vm, V3_MEM_CORE_ANY, PCI_MEM32_BASE(new_val), 
900                                  PCI_MEM32_BASE(new_val) + (bar->num_pages * PAGE_SIZE_4KB),
901                                  bar->mem_read, bar->mem_write, pci_dev->priv_data);
902             } else {
903                 PrintError(VM_NONE, VCORE_NONE, "Write hooks not supported for PCI\n");
904                 return -1;
905             }
906
907             bar->val = new_val;
908
909             break;
910         }
911         case PCI_BAR_NONE: {
912             PrintDebug(VM_NONE, VCORE_NONE, "Reprogramming an unsupported BAR register (Dev=%s) (bar=%d) (val=%x)\n", 
913                        pci_dev->name, bar_num, new_val);
914             break;
915         }
916         default:
917             PrintError(VM_NONE, VCORE_NONE, "Invalid Bar Reg updated (bar=%d)\n", bar_num);
918             return -1;
919     }
920
921     return 0;
922 }
923
924
925 static int data_port_write(struct guest_info * core, uint16_t port, void * src, uint_t length, void * priv_data) {
926     struct pci_internal * pci_state = priv_data;
927     struct pci_device * pci_dev = NULL;
928     uint_t reg_num = (pci_state->addr_reg.hi_reg_num << 16) +(pci_state->addr_reg.reg_num << 2) + (port & 0x3);
929     int i = 0;
930     int ret = length;
931
932     if (pci_state->addr_reg.bus_num != 0) {
933         return length;
934     }
935
936     PrintDebug(VM_NONE, VCORE_NONE, "Writing PCI Data register. bus = %d, dev = %d, fn = %d, reg = %d (0x%x) addr_reg = 0x%x (val=0x%x, len=%d)\n", 
937                pci_state->addr_reg.bus_num, 
938                pci_state->addr_reg.dev_num, 
939                pci_state->addr_reg.fn_num,
940                reg_num, reg_num, 
941                pci_state->addr_reg.val,
942                *(uint32_t *)src, length);
943
944
945     pci_dev = get_device(&(pci_state->bus_list[0]), pci_state->addr_reg.dev_num, pci_state->addr_reg.fn_num);
946     
947     if (pci_dev == NULL) {
948         PrintError(VM_NONE, VCORE_NONE, "Writing configuration space for non-present device (dev_num=%d)\n", 
949                    pci_state->addr_reg.dev_num); 
950         return -1;
951     }
952
953     /* update the config space
954        If a hook has been registered for a given region, call the hook with the max write length
955     */ 
956     while (length > 0) {
957         struct cfg_range_hook * cfg_hook  = find_cfg_range_hook(pci_dev, reg_num + i, 1);
958
959         if (cfg_hook) {
960             uint_t range_len = cfg_hook->length - ((reg_num + i) - cfg_hook->start);
961             range_len = (range_len > length) ? length : range_len;
962             
963             if (cfg_hook->write) {
964                 cfg_hook->write(pci_dev, reg_num + i, (void *)(src + i), range_len, cfg_hook->private_data);
965             } 
966
967             length -= range_len;
968             i += range_len;
969         } else {
970             // send the writes to the cached config space, and to the generic callback if present
971             uint8_t mask = 0xff;
972
973             if (reg_num < 64) {
974                 mask = pci_hdr_write_mask_00[reg_num + i];
975             }
976             
977             if (mask != 0) {
978                 uint8_t new_val = *(uint8_t *)(src + i);
979                 uint8_t old_val = pci_dev->config_space[reg_num + i];
980
981                 pci_dev->config_space[reg_num + i] = ((new_val & mask) | (old_val & ~mask));
982                 
983                 if (pci_dev->config_write) {
984                     pci_dev->config_write(pci_dev, reg_num + i, &(pci_dev->config_space[reg_num + i]), 1, pci_dev->priv_data);
985                 }
986             }       
987
988             length--;
989             i++;
990         }
991     }
992
993     return ret;
994 }
995
996
997
998 static int exp_rom_write(struct pci_device * pci_dev, uint32_t offset, 
999                          void * src, uint_t length, void * private_data) {
1000     int bar_offset = offset & ~0x03;
1001
1002     if (pci_dev->config_write) {
1003         pci_dev->config_write(pci_dev, offset, src, length, pci_dev->priv_data);
1004     }
1005
1006     if (pci_dev->exp_rom_update) {
1007         pci_dev->exp_rom_update(pci_dev, (void *)(pci_dev->config_space + bar_offset), pci_dev->priv_data);
1008         
1009         return 0;
1010     }
1011
1012     PrintError(VM_NONE, VCORE_NONE, "Expansion ROM update not handled. Will appear to not Exist\n");
1013
1014     return 0;
1015 }
1016
1017
1018 static int cmd_write(struct pci_device * pci_dev, uint32_t offset, 
1019                      void * src, uint_t length, void * private_data) {
1020
1021     PrintDebug(VM_NONE, VCORE_NONE, "PCI command update!\n");
1022
1023     int i = 0;
1024
1025     struct pci_cmd_reg old_cmd;
1026     struct pci_cmd_reg new_cmd;
1027     if (pci_dev->config_write) {
1028         pci_dev->config_write(pci_dev, offset, src, length, pci_dev->priv_data);
1029     }
1030     old_cmd.val = pci_dev->config_header.command;
1031
1032     for (i = 0; i < length; i++) {
1033         uint8_t mask = pci_hdr_write_mask_00[offset + i];
1034         uint8_t new_val = *(uint8_t *)(src + i);
1035         uint8_t old_val = pci_dev->config_space[offset + i];
1036
1037         pci_dev->config_space[offset + i] = ((new_val & mask) | (old_val & ~mask));
1038     }
1039
1040     new_cmd.val = pci_dev->config_header.command;
1041
1042     if (pci_dev->cmd_update) {
1043         if ((new_cmd.intx_disable == 1) && (old_cmd.intx_disable == 0)) {
1044             pci_dev->irq_type = IRQ_NONE;
1045             pci_dev->cmd_update(pci_dev, PCI_CMD_INTX_DISABLE, 0, pci_dev->priv_data);
1046         } else if ((new_cmd.intx_disable == 0) && (old_cmd.intx_disable == 1)) {
1047             pci_dev->irq_type = IRQ_INTX;
1048             pci_dev->cmd_update(pci_dev, PCI_CMD_INTX_ENABLE, 0, pci_dev->priv_data);
1049         }
1050
1051
1052         if ((new_cmd.dma_enable == 1) && (old_cmd.dma_enable == 0)) {
1053             pci_dev->cmd_update(pci_dev, PCI_CMD_DMA_ENABLE, 0, pci_dev->priv_data);
1054         } else if ((new_cmd.dma_enable == 0) && (old_cmd.dma_enable == 1)) {
1055             pci_dev->cmd_update(pci_dev, PCI_CMD_DMA_DISABLE, 0, pci_dev->priv_data);
1056         }
1057     }
1058
1059     return 0;
1060 }
1061
1062
1063 static void init_pci_busses(struct pci_internal * pci_state) {
1064     int i;
1065
1066     for (i = 0; i < PCI_BUS_COUNT; i++) {
1067         pci_state->bus_list[i].bus_num = i;
1068         pci_state->bus_list[i].devices.rb_node = NULL;
1069         memset(pci_state->bus_list[i].dev_map, 0, sizeof(pci_state->bus_list[i].dev_map));
1070     }
1071 }
1072
1073
1074 static int pci_free(struct pci_internal * pci_state) {
1075     int i;
1076
1077
1078     // cleanup devices
1079     for (i = 0; i < PCI_BUS_COUNT; i++) {
1080         struct pci_bus * bus = &(pci_state->bus_list[i]);
1081         struct rb_node * node = v3_rb_first(&(bus->devices));
1082         struct pci_device * dev = NULL;
1083
1084         while (node) {
1085             dev = rb_entry(node, struct pci_device, dev_tree_node);
1086             node = v3_rb_next(node);
1087             
1088             v3_rb_erase(&(dev->dev_tree_node), &(bus->devices));
1089             
1090             // Free config range hooks
1091             { 
1092                 struct cfg_range_hook * hook = NULL;
1093                 struct cfg_range_hook * tmp = NULL;
1094                 list_for_each_entry_safe(hook, tmp, &(dev->cfg_hooks), list_node) {
1095                     list_del(&(hook->list_node));
1096                     V3_Free(hook);
1097                 }
1098             }
1099
1100             // Free caps
1101             {
1102                 struct pci_cap * cap = NULL;
1103                 struct pci_cap * tmp = NULL;
1104                 list_for_each_entry_safe(cap, tmp, &(dev->cfg_hooks), cap_node) {
1105                     list_del(&(cap->cap_node));
1106                     V3_Free(cap);
1107                 }
1108             }
1109
1110             V3_Free(dev);
1111         }
1112
1113     }
1114     
1115     V3_Free(pci_state);
1116     return 0;
1117 }
1118
1119 #ifdef V3_CONFIG_CHECKPOINT
1120
1121 #include <palacios/vmm_sprintf.h>
1122
1123 static int pci_save_extended(struct v3_chkpt *chkpt, char *id, void * private_data) {
1124     struct pci_internal * pci = (struct pci_internal *)private_data;
1125     struct v3_chkpt_ctx *ctx=0;
1126     char buf[128];
1127     int i = 0;    
1128
1129     ctx = v3_chkpt_open_ctx(chkpt,id);
1130
1131     if (!ctx) { 
1132       PrintError(VM_NONE, VCORE_NONE, "Unable to open base context on save\n");
1133       goto savefailout;
1134     }
1135
1136     V3_CHKPT_SAVE(ctx, "ADDR_REG", pci->addr_reg.val, savefailout);
1137     V3_CHKPT_SAVE(ctx, "IO_BASE", pci->dev_io_base, savefailout);
1138
1139     v3_chkpt_close_ctx(ctx); ctx=0;
1140
1141     for (i = 0; i < PCI_BUS_COUNT; i++) {
1142         struct pci_bus * bus = &(pci->bus_list[i]);
1143         struct rb_node * node = v3_rb_first(&(bus->devices));
1144         struct pci_device * dev = NULL;
1145
1146         snprintf(buf, 128, "%s-%d", id, i);
1147         
1148         ctx = v3_chkpt_open_ctx(chkpt, buf);
1149         
1150         if (!ctx) { 
1151           PrintError(VM_NONE, VCORE_NONE, "Failed to open context for %s\n", buf);
1152           goto savefailout;
1153         }
1154
1155         // nothing actually saved on the bus context... (later expansion)
1156
1157         v3_chkpt_close_ctx(ctx); ctx=0;
1158
1159         while (node) {
1160             int bar_idx = 0;
1161             dev = rb_entry(node, struct pci_device, dev_tree_node);
1162
1163             snprintf(buf, 128, "%s-%d.%d-%d", id, i, dev->dev_num, dev->fn_num);
1164
1165             ctx = v3_chkpt_open_ctx(chkpt, buf);
1166             
1167             if (!ctx) { 
1168               PrintError(VM_NONE, VCORE_NONE, "Failed to open context for device\n");
1169               goto savefailout;
1170             }
1171             
1172             V3_CHKPT_SAVE(ctx, "CONFIG_SPACE", dev->config_space, savefailout);
1173
1174             for (bar_idx = 0; bar_idx < 6; bar_idx++) {
1175                 snprintf(buf, 128, "BAR-%d", bar_idx);
1176                 V3_CHKPT_SAVE(ctx, buf, dev->bar[bar_idx].val, savefailout);
1177             }
1178             
1179             v3_chkpt_close_ctx(ctx); ctx=0;
1180
1181             node = v3_rb_next(node);
1182         }
1183     }
1184
1185 // goodout:
1186
1187     return 0;
1188     
1189  savefailout:
1190     PrintError(VM_NONE, VCORE_NONE, "Failed to save PCI\n");
1191     if (ctx) { v3_chkpt_close_ctx(ctx); }
1192     return -1;
1193
1194 }
1195
1196
1197 static int pci_load_extended(struct v3_chkpt *chkpt, char *id, void * private_data) {
1198     struct pci_internal * pci = (struct pci_internal *)private_data;
1199     struct v3_chkpt_ctx *ctx=0;
1200     char buf[128];
1201     int i = 0;    
1202     
1203     ctx = v3_chkpt_open_ctx(chkpt,id);
1204
1205     if (!ctx) { 
1206       PrintError(VM_NONE, VCORE_NONE, "Unable to open base context on load\n");
1207       goto loadfailout;
1208     }
1209
1210     V3_CHKPT_LOAD(ctx, "ADDR_REG", pci->addr_reg.val, loadfailout);
1211     V3_CHKPT_LOAD(ctx, "IO_BASE", pci->dev_io_base, loadfailout);
1212
1213     v3_chkpt_close_ctx(ctx); ctx=0;
1214
1215     for (i = 0; i < PCI_BUS_COUNT; i++) {
1216         struct pci_bus * bus = &(pci->bus_list[i]);
1217         struct rb_node * node = v3_rb_first(&(bus->devices));
1218         struct pci_device * dev = NULL;
1219
1220         snprintf(buf, 128, "pci-%d", i);
1221         
1222         ctx = v3_chkpt_open_ctx(chkpt, buf);
1223         
1224         if (!ctx) { 
1225           PrintError(VM_NONE, VCORE_NONE, "Failed to open context for %s\n", buf);
1226           goto loadfailout;
1227         }
1228
1229         // nothing actually saved on the bus context... (later expansion)
1230
1231         v3_chkpt_close_ctx(ctx); ctx=0;
1232
1233         while (node) {
1234             int bar_idx = 0;
1235             dev = rb_entry(node, struct pci_device, dev_tree_node);
1236
1237             snprintf(buf, 128, "pci-%d.%d-%d", i, dev->dev_num, dev->fn_num);
1238
1239             ctx = v3_chkpt_open_ctx(chkpt, buf);
1240             
1241             if (!ctx) { 
1242               PrintError(VM_NONE, VCORE_NONE, "Failed to open context for device\n");
1243               goto loadfailout;
1244             }
1245
1246             V3_CHKPT_LOAD(ctx, "CONFIG_SPACE", dev->config_space, loadfailout);
1247
1248             for (bar_idx = 0; bar_idx < 6; bar_idx++) {
1249                 snprintf(buf, 128, "BAR-%d", bar_idx);
1250                 V3_CHKPT_LOAD(ctx, buf, dev->bar[bar_idx].val, loadfailout);
1251             }
1252
1253             v3_chkpt_close_ctx(ctx); ctx=0;
1254
1255             node = v3_rb_next(node);
1256         }
1257     }
1258
1259 // goodout:
1260     return 0;
1261
1262  loadfailout:
1263     PrintError(VM_NONE, VCORE_NONE, "Failed to load PCI\n");
1264     if (ctx) { v3_chkpt_close_ctx(ctx); }
1265     return -1;
1266     
1267 }
1268
1269
1270 #endif
1271
1272
1273
1274
1275 static struct v3_device_ops dev_ops = {
1276     .free = (int (*)(void *))pci_free,
1277 #ifdef V3_CONFIG_CHECKPOINT
1278     .save_extended = pci_save_extended,
1279     .load_extended = pci_load_extended
1280 #endif
1281 };
1282
1283
1284
1285
1286 static int pci_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
1287     struct pci_internal * pci_state = V3_Malloc(sizeof(struct pci_internal));
1288
1289     if (!pci_state) {
1290         PrintError(vm, VCORE_NONE, "Cannot allocate in init\n");
1291         return -1;
1292     }
1293
1294     int i = 0;
1295     char * dev_id = v3_cfg_val(cfg, "ID");
1296     int ret = 0;
1297     
1298     PrintDebug(vm, VCORE_NONE, "PCI internal at %p\n",(void *)pci_state);
1299     
1300     struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, pci_state);
1301     
1302     if (dev == NULL) {
1303         PrintError(vm, VCORE_NONE, "Could not attach device %s\n", dev_id);
1304         V3_Free(pci_state);
1305         return -1;
1306     }
1307
1308     
1309     pci_state->addr_reg.val = 0; 
1310     pci_state->dev_io_base = PCI_DEV_IO_PORT_BASE;
1311
1312     init_pci_busses(pci_state);
1313     
1314     PrintDebug(vm, VCORE_NONE, "Sizeof config header=%d\n", (int)sizeof(struct pci_config_header));
1315     
1316     for (i = 0; i < 4; i++) {
1317         ret |= v3_dev_hook_io(dev, CONFIG_ADDR_PORT + i, &addr_port_read, &addr_port_write);
1318         ret |= v3_dev_hook_io(dev, CONFIG_DATA_PORT + i, &data_port_read, &data_port_write);
1319     }
1320     
1321     if (ret != 0) {
1322         PrintError(vm, VCORE_NONE, "Error hooking PCI IO ports\n");
1323         v3_remove_device(dev);
1324         return -1;
1325     }
1326
1327     return 0;
1328 }
1329
1330
1331 device_register("PCI", pci_init)
1332
1333
1334 static inline int init_bars(struct v3_vm_info * vm, struct pci_device * pci_dev) {
1335     int i = 0;
1336
1337     for (i = 0; i < 6; i++) {
1338         int bar_offset = 0x10 + (4 * i);
1339         struct v3_pci_bar * bar = &(pci_dev->bar[i]);
1340
1341         if (bar->type == PCI_BAR_IO) {
1342             int j = 0;
1343             bar->mask = (~((bar->num_ports) - 1)) | 0x01;
1344
1345             if (bar->default_base_port != 0xffff) {
1346                 bar->val = bar->default_base_port & bar->mask;
1347             } else {
1348                 bar->val = 0;
1349             }
1350
1351             bar->val |= 0x00000001;
1352
1353             for (j = 0; j < bar->num_ports; j++) {
1354                 // hook IO
1355                 if (bar->default_base_port != 0xffff) {
1356                     if (v3_hook_io_port(vm, bar->default_base_port + j,
1357                                         bar->io_read, bar->io_write, 
1358                                         bar->private_data) == -1) {
1359                         PrintError(vm, VCORE_NONE, "Could not hook default io port %x\n", bar->default_base_port + j);
1360                         return -1;
1361                     }
1362                 }
1363             }
1364
1365             *(uint32_t *)(pci_dev->config_space + bar_offset) = bar->val;
1366
1367         } else if (bar->type == PCI_BAR_MEM32) {
1368             bar->mask = ~((bar->num_pages << 12) - 1);
1369             bar->mask |= 0xf; // preserve the configuration flags
1370
1371
1372             if (bar->default_base_addr != 0xffffffff) {
1373                 bar->val = bar->default_base_addr & bar->mask;
1374             } else {
1375                 bar->val = 0;
1376             }
1377
1378             // hook memory
1379             if (bar->mem_read) {
1380                 // full hook
1381                 v3_hook_full_mem(vm, V3_MEM_CORE_ANY, bar->default_base_addr,
1382                                  bar->default_base_addr + (bar->num_pages * PAGE_SIZE_4KB),
1383                                  bar->mem_read, bar->mem_write, pci_dev->priv_data);
1384             } else if (bar->mem_write) {
1385                 // write hook
1386                 PrintError(vm, VCORE_NONE, "Write hooks not supported for PCI devices\n");
1387                 return -1;
1388                 /*
1389                   v3_hook_write_mem(pci_dev->vm_dev->vm, bar->default_base_addr, 
1390                   bar->default_base_addr + (bar->num_pages * PAGE_SIZE_4KB),
1391                   bar->mem_write, pci_dev->vm_dev);
1392                 */
1393             } else {
1394                 // set the prefetchable flag...
1395                 bar->val |= 0x00000008;
1396             }
1397
1398
1399             *(uint32_t *)(pci_dev->config_space + bar_offset) = bar->val;
1400
1401         } else if (bar->type == PCI_BAR_MEM24) {
1402             PrintError(vm, VCORE_NONE, "16 Bit memory ranges not supported (reg: %d)\n", i);
1403             return -1;
1404         } else if (bar->type == PCI_BAR_NONE) {
1405             bar->val = 0x00000000;
1406             bar->mask = 0x00000000; // This ensures that all updates will be dropped
1407             *(uint32_t *)(pci_dev->config_space + bar_offset) = bar->val;
1408         } else if (bar->type == PCI_BAR_PASSTHROUGH) {
1409
1410             // Call the bar init function to get the local cached value
1411             bar->bar_init(i, &(bar->val), bar->private_data);
1412
1413             // Copy back changes it made
1414             *(uint32_t *)(pci_dev->config_space + bar_offset) = bar->val;
1415
1416         } else {
1417             PrintError(vm, VCORE_NONE, "Invalid BAR type for bar #%d\n", i);
1418             return -1;
1419         }
1420
1421         v3_pci_hook_config_range(pci_dev, bar_offset, 4, bar_update, NULL, bar);
1422     }
1423
1424     return 0;
1425 }
1426
1427
1428 int v3_pci_set_irq_bridge(struct  vm_device * pci_bus, int bus_num, 
1429                           int (*raise_pci_irq)(struct pci_device * pci_dev, void * dev_data, struct v3_irq * vec),
1430                           int (*lower_pci_irq)(struct pci_device * pci_dev, void * dev_data, struct v3_irq * vec),
1431                           void * priv_data) {
1432     struct pci_internal * pci_state = (struct pci_internal *)pci_bus->private_data;
1433
1434
1435     pci_state->bus_list[bus_num].raise_pci_irq = raise_pci_irq;
1436     pci_state->bus_list[bus_num].lower_pci_irq = lower_pci_irq;
1437     pci_state->bus_list[bus_num].irq_dev_data = priv_data;
1438
1439     return 0;
1440 }
1441
1442 int v3_pci_raise_irq(struct vm_device * pci_bus, struct pci_device * dev, uint32_t vec_index) {
1443    struct v3_irq vec;
1444
1445    vec.ack = NULL;
1446    vec.private_data = NULL;
1447    vec.irq = vec_index;
1448
1449    return v3_pci_raise_acked_irq(pci_bus, dev, vec);
1450 }
1451
1452 int v3_pci_lower_irq(struct vm_device * pci_bus, struct pci_device * dev, uint32_t vec_index) {
1453     struct v3_irq vec;
1454
1455     vec.irq = vec_index;
1456     vec.ack = NULL;
1457     vec.private_data = NULL;
1458     
1459     return v3_pci_lower_acked_irq(pci_bus, dev, vec);
1460 }
1461
1462 int v3_pci_raise_acked_irq(struct vm_device * pci_bus, struct pci_device * dev, struct v3_irq vec) {
1463    struct pci_internal * pci_state = (struct pci_internal *)pci_bus->private_data;
1464    struct pci_bus * bus = &(pci_state->bus_list[dev->bus_num]);
1465
1466
1467    if (dev->irq_type == IRQ_INTX) {
1468        return bus->raise_pci_irq(dev, bus->irq_dev_data, &vec);
1469    } else if (dev->irq_type == IRQ_MSI) {
1470        struct v3_gen_ipi ipi;
1471        struct msi_addr * addr = NULL;
1472        struct msi_data * data = NULL;       
1473        
1474        if (dev->msi_cap->cap_64bit) {
1475            if (dev->msi_cap->per_vect_mask) {
1476                struct msi64_pervec_msg_addr * msi = (void *)dev->msi_cap;
1477                addr = &(msi->addr);
1478                data = &(msi->data);
1479            } else {
1480                struct msi64_msg_addr * msi = (void *)dev->msi_cap;
1481                addr = &(msi->addr);
1482                data = &(msi->data);
1483            }
1484        } else {
1485            struct msi32_msg_addr * msi = (void *)dev->msi_cap;
1486            addr = &(msi->addr);
1487            data = &(msi->data);
1488        }
1489
1490        memset(&ipi, 0, sizeof(struct v3_gen_ipi));
1491
1492        // decode MSI fields into IPI
1493
1494        ipi.vector = data->vector + vec.irq;
1495        ipi.mode = data->del_mode;
1496        ipi.logical = addr->dst_mode;
1497        ipi.trigger_mode = data->trig_mode;
1498        ipi.dst_shorthand = 0;
1499        ipi.dst = addr->dst_id;
1500        
1501
1502        v3_apic_send_ipi(dev->vm, &ipi, dev->apic_dev);
1503
1504        return 0;       
1505    } else if (dev->irq_type == IRQ_MSIX) {
1506        addr_t msix_table_gpa = 0;
1507        struct msix_table * msix_table = NULL;
1508        uint_t bar_idx = dev->msix_cap->bir;
1509        struct v3_gen_ipi ipi;
1510        struct msi_addr * addr = NULL;
1511        struct msi_data * data = NULL;   
1512        
1513        if (dev->bar[bar_idx].type != PCI_BAR_MEM32) {
1514            PrintError(VM_NONE, VCORE_NONE, "Non 32bit MSIX BAR registers are not supported\n");
1515            return -1;
1516        }
1517
1518        msix_table_gpa = dev->bar[bar_idx].val;
1519        msix_table_gpa += dev->msix_cap->table_offset;
1520
1521        if (v3_gpa_to_hva(&(dev->vm->cores[0]), msix_table_gpa, (void *)&(msix_table)) != 0) {
1522            PrintError(VM_NONE, VCORE_NONE, "Could not translate MSIX Table GPA (%p)\n", (void *)msix_table_gpa);
1523            return -1;
1524        }
1525        
1526        memset(&ipi, 0, sizeof(struct v3_gen_ipi));
1527
1528        data = &(msix_table->entries[vec.irq].data);
1529        addr = &(msix_table->entries[vec.irq].addr);;
1530        
1531        // decode MSIX fields into IPI
1532        ipi.vector = data->vector + vec.irq;
1533        ipi.mode = data->del_mode;
1534        ipi.logical = addr->dst_mode;
1535        ipi.trigger_mode = data->trig_mode;
1536        ipi.dst_shorthand = 0;
1537        ipi.dst = addr->dst_id;
1538        
1539
1540
1541        V3_Print(VM_NONE, VCORE_NONE, "Decode MSIX\n");
1542
1543        v3_apic_send_ipi(dev->vm, &ipi, dev->apic_dev);
1544
1545        return 0;
1546    } 
1547    
1548    // Should never get here
1549    return -1;
1550
1551 }
1552
1553 int v3_pci_lower_acked_irq(struct vm_device * pci_bus, struct pci_device * dev, struct v3_irq vec) {
1554     if (dev->irq_type == IRQ_INTX) {
1555         struct pci_internal * pci_state = (struct pci_internal *)pci_bus->private_data;
1556         struct pci_bus * bus = &(pci_state->bus_list[dev->bus_num]);
1557         
1558         return bus->lower_pci_irq(dev, bus->irq_dev_data, &vec);
1559     } else {
1560         return -1;
1561     }
1562 }
1563
1564
1565 // if dev_num == -1, auto assign 
1566 struct pci_device * v3_pci_register_device(struct vm_device * pci,
1567                                            pci_device_type_t dev_type, 
1568                                            int bus_num,
1569                                            int dev_num,
1570                                            int fn_num,
1571                                            const char * name,
1572                                            struct v3_pci_bar * bars,
1573                                            int (*config_write)(struct pci_device * pci_dev, uint32_t reg_num, void * src, 
1574                                                                uint_t length, void * priv_data),
1575                                            int (*config_read)(struct pci_device * pci_dev, uint32_t reg_num, void * dst, 
1576                                                               uint_t length, void * priv_data),
1577                                            int (*cmd_update)(struct pci_device * pci_dev, pci_cmd_t cmd, uint64_t arg, void * priv_data),
1578                                            int (*exp_rom_update)(struct pci_device * pci_dev, uint32_t * src, void * priv_data),
1579                                            void * priv_data) {
1580
1581     struct pci_internal * pci_state = (struct pci_internal *)pci->private_data;
1582     struct pci_bus * bus = &(pci_state->bus_list[bus_num]);
1583     struct pci_device * pci_dev = NULL;
1584     int i;
1585
1586     if (dev_num > MAX_BUS_DEVICES) {
1587         PrintError(VM_NONE, VCORE_NONE, "Requested Invalid device number (%d)\n", dev_num);
1588         return NULL;
1589     }
1590
1591     if (dev_num == PCI_AUTO_DEV_NUM) {
1592         PrintDebug(VM_NONE, VCORE_NONE, "Searching for free device number\n");
1593         if ((dev_num = get_free_dev_num(bus)) == -1) {
1594             PrintError(VM_NONE, VCORE_NONE, "No more available PCI slots on bus %d\n", bus->bus_num);
1595             return NULL;
1596         }
1597         V3_Print(VM_NONE, VCORE_NONE,"assigning dev num %d to device (%s, busnum=%d,fnnum=%d)\n", dev_num, name, bus->bus_num, fn_num);
1598     }
1599     
1600     PrintDebug(VM_NONE, VCORE_NONE, "Checking for PCI Device\n");
1601
1602     if (get_device(bus, dev_num, fn_num) != NULL) {
1603         PrintError(VM_NONE, VCORE_NONE, "PCI Device already registered at slot %d on bus %d\n", 
1604                    dev_num, bus->bus_num);
1605         return NULL;
1606     }
1607
1608     
1609     pci_dev = (struct pci_device *)V3_Malloc(sizeof(struct pci_device));
1610
1611     if (pci_dev == NULL) {
1612         PrintError(VM_NONE, VCORE_NONE, "Could not allocate pci device\n");
1613         return NULL;
1614     }
1615
1616     memset(pci_dev, 0, sizeof(struct pci_device));
1617
1618
1619     pci_dev->type = dev_type;
1620     
1621     switch (pci_dev->type) {
1622         case PCI_STD_DEVICE:
1623             pci_dev->config_header.header_type = 0x00;
1624             break;
1625         case PCI_MULTIFUNCTION:
1626             pci_dev->config_header.header_type = 0x80;
1627             break;
1628         default:
1629             PrintError(VM_NONE, VCORE_NONE, "Unhandled PCI Device Type: %d\n", dev_type);
1630             return NULL;
1631     }
1632
1633
1634
1635     pci_dev->bus_num = bus_num;
1636     pci_dev->dev_num = dev_num;
1637     pci_dev->fn_num = fn_num;
1638
1639     strncpy(pci_dev->name, name, sizeof(pci_dev->name));
1640     pci_dev->name[sizeof(pci_dev->name)-1] = 0;
1641     pci_dev->vm = pci->vm;
1642     pci_dev->priv_data = priv_data;
1643
1644     INIT_LIST_HEAD(&(pci_dev->cfg_hooks));
1645     INIT_LIST_HEAD(&(pci_dev->capabilities));
1646
1647     
1648     {
1649         // locate APIC for MSI/MSI-X
1650         pci_dev->apic_dev = v3_find_dev(pci->vm, "apic");
1651     }
1652
1653     // register update callbacks
1654     pci_dev->config_write = config_write;
1655     pci_dev->config_read = config_read;
1656     pci_dev->cmd_update = cmd_update;
1657     pci_dev->exp_rom_update = exp_rom_update;
1658
1659
1660
1661     if (config_read) {
1662         int i = 0;
1663
1664         // Only 256 bytes for now, should expand it in the future
1665         for (i = 0; i < 256; i++) {
1666             config_read(pci_dev, i, &(pci_dev->config_space[i]), 1, pci_dev->priv_data);
1667         }
1668     }
1669
1670     V3_Print(VM_NONE, VCORE_NONE, "Scanning for Capabilities\n");
1671
1672     // scan for caps
1673     scan_pci_caps(pci_dev);
1674
1675     pci_dev->irq_type = IRQ_INTX;
1676
1677     V3_Print(VM_NONE, VCORE_NONE, "Caps scanned\n");
1678
1679     // hook important regions
1680     v3_pci_hook_config_range(pci_dev, 0x30, 4, exp_rom_write, NULL, NULL);  // ExpRom
1681     v3_pci_hook_config_range(pci_dev, 0x04, 2, cmd_write, NULL, NULL);      // CMD Reg
1682     // * Status resets
1683     // * Drop BIST
1684     // 
1685
1686     
1687
1688     //copy bars
1689     for (i = 0; i < 6; i ++) {
1690         pci_dev->bar[i].type = bars[i].type;
1691         pci_dev->bar[i].private_data = bars[i].private_data;
1692
1693         if (pci_dev->bar[i].type == PCI_BAR_IO) {
1694             pci_dev->bar[i].num_ports = bars[i].num_ports;
1695
1696             // This is a horrible HACK becaues the BIOS is supposed to set the PCI base ports 
1697             // And if the BIOS doesn't, Linux just happily overlaps device port assignments
1698             if (bars[i].default_base_port != (uint16_t)-1) {
1699                 pci_dev->bar[i].default_base_port = bars[i].default_base_port;
1700             } else {
1701                 pci_dev->bar[i].default_base_port = pci_state->dev_io_base;
1702                 pci_state->dev_io_base += ( 0x100 * ((bars[i].num_ports / 0x100) + 1) );
1703             }
1704
1705             pci_dev->bar[i].io_read = bars[i].io_read;
1706             pci_dev->bar[i].io_write = bars[i].io_write;
1707         } else if (pci_dev->bar[i].type == PCI_BAR_MEM32) {
1708             pci_dev->bar[i].num_pages = bars[i].num_pages;
1709             pci_dev->bar[i].default_base_addr = bars[i].default_base_addr;
1710             pci_dev->bar[i].mem_read = bars[i].mem_read;
1711             pci_dev->bar[i].mem_write = bars[i].mem_write;
1712         } else if (pci_dev->bar[i].type == PCI_BAR_PASSTHROUGH) {
1713             pci_dev->bar[i].bar_init = bars[i].bar_init;
1714             pci_dev->bar[i].bar_write = bars[i].bar_write;
1715         } else {
1716             pci_dev->bar[i].num_pages = 0;
1717             pci_dev->bar[i].default_base_addr = 0;
1718             pci_dev->bar[i].mem_read = NULL;
1719             pci_dev->bar[i].mem_write = NULL;
1720         }
1721     }
1722
1723     if (init_bars(pci->vm, pci_dev) == -1) {
1724         PrintError(VM_NONE, VCORE_NONE, "could not initialize bar registers\n");
1725         return NULL;
1726     }
1727
1728     // add the device
1729     add_device_to_bus(bus, pci_dev);
1730
1731 #ifdef V3_CONFIG_DEBUG_PCI
1732     pci_dump_state(pci_state);
1733 #endif
1734
1735     return pci_dev;
1736 }
1737