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.


29c54358bd403511e7075f079e9a32d565200f28
[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
32 #include <devices/pci.h>
33 #include <devices/pci_types.h>
34
35 #ifndef CONFIG_DEBUG_PCI
36 #undef PrintDebug
37 #define PrintDebug(fmt, args...)
38 #endif
39
40
41 #define CONFIG_ADDR_PORT    0x0cf8
42 #define CONFIG_DATA_PORT    0x0cfc
43
44 #define PCI_DEV_IO_PORT_BASE 0xc000
45
46 #define PCI_BUS_COUNT 1
47
48 // This must always be a multiple of 8
49 #define MAX_BUS_DEVICES 32
50
51 struct pci_addr_reg {
52     union {
53         uint32_t val;
54         struct {
55             uint_t rsvd       : 2;
56             uint_t reg_num    : 6;
57             uint_t fn_num     : 3;
58             uint_t dev_num    : 5;
59             uint_t bus_num    : 8;
60             uint_t rsvd2      : 7;
61             uint_t enable     : 1;
62         } __attribute__((packed));
63     } __attribute__((packed));
64 } __attribute__((packed));
65
66
67
68
69
70 struct pci_bus {
71     int bus_num;
72
73     // Red Black tree containing all attached devices
74     struct rb_root devices;
75
76     // Bitmap of the allocated device numbers
77     uint8_t dev_map[MAX_BUS_DEVICES / 8];
78
79
80     int (*raise_pci_irq)(struct vm_device * dev, struct pci_device * pci_dev);
81     int (*lower_pci_irq)(struct vm_device * dev, struct pci_device * pci_dev);
82     struct vm_device * irq_bridge_dev;
83 };
84
85
86
87 struct pci_internal {
88     // Configuration address register
89     struct pci_addr_reg addr_reg;
90
91     // Base IO Port which PCI devices will register with...
92     uint16_t dev_io_base; 
93
94     // Attached Busses
95     struct pci_bus bus_list[PCI_BUS_COUNT];
96 };
97
98
99
100
101
102 #ifdef CONFIG_DEBUG_PCI
103
104 static void pci_dump_state(struct pci_internal * pci_state) {
105     struct rb_node * node = v3_rb_first(&(pci_state->bus_list[0].devices));
106     struct pci_device * tmp_dev = NULL;
107     
108     PrintDebug("===PCI: Dumping state Begin ==========\n");
109     
110     do {
111         tmp_dev = rb_entry(node, struct pci_device, dev_tree_node);
112
113         PrintDebug("PCI Device Number: %d (%s):\n", tmp_dev->dev_num,  tmp_dev->name);
114         PrintDebug("irq = %d\n", tmp_dev->config_header.intr_line);
115         PrintDebug("Vend ID: 0x%x\n", tmp_dev->config_header.vendor_id);
116         PrintDebug("Device ID: 0x%x\n", tmp_dev->config_header.device_id);
117
118     } while ((node = v3_rb_next(node)));
119     
120     PrintDebug("====PCI: Dumping state End==========\n");
121 }
122
123 #endif
124
125
126
127
128 // Scan the dev_map bitmap for the first '0' bit
129 static int get_free_dev_num(struct pci_bus * bus) {
130     int i, j;
131
132     for (i = 0; i < sizeof(bus->dev_map); i++) {
133         PrintDebug("i=%d\n", i);
134         if (bus->dev_map[i] != 0xff) {
135             // availability
136             for (j = 0; j < 8; j++) {
137                 PrintDebug("\tj=%d\n", j);
138                 if (!(bus->dev_map[i] & (0x1 << j))) {
139                     return ((i * 8) + j);
140                 }
141             }
142         }
143     }
144
145     return -1;
146 }
147
148 static void allocate_dev_num(struct pci_bus * bus, int dev_num) {
149     int major = (dev_num / 8);
150     int minor = dev_num % 8;
151
152     bus->dev_map[major] |= (0x1 << minor);
153 }
154
155
156
157 static inline 
158 struct pci_device * __add_device_to_bus(struct pci_bus * bus, struct pci_device * dev) {
159
160   struct rb_node ** p = &(bus->devices.rb_node);
161   struct rb_node * parent = NULL;
162   struct pci_device * tmp_dev = NULL;
163
164   while (*p) {
165     parent = *p;
166     tmp_dev = rb_entry(parent, struct pci_device, dev_tree_node);
167
168     if (dev->devfn < tmp_dev->devfn) {
169       p = &(*p)->rb_left;
170     } else if (dev->devfn > tmp_dev->devfn) {
171       p = &(*p)->rb_right;
172     } else {
173       return tmp_dev;
174     }
175   }
176
177   rb_link_node(&(dev->dev_tree_node), parent, p);
178
179   return NULL;
180 }
181
182
183 static inline 
184 struct pci_device * add_device_to_bus(struct pci_bus * bus, struct pci_device * dev) {
185
186   struct pci_device * ret = NULL;
187
188   if ((ret = __add_device_to_bus(bus, dev))) {
189     return ret;
190   }
191
192   v3_rb_insert_color(&(dev->dev_tree_node), &(bus->devices));
193
194   allocate_dev_num(bus, dev->dev_num);
195
196   return NULL;
197 }
198
199
200 static struct pci_device * get_device(struct pci_bus * bus, uint8_t dev_num, uint8_t fn_num) {
201     struct rb_node * n = bus->devices.rb_node;
202     struct pci_device * dev = NULL;
203     uint8_t devfn = ((dev_num & 0x1f) << 3) | (fn_num & 0x7);
204
205     while (n) {
206         dev = rb_entry(n, struct pci_device, dev_tree_node);
207         
208         if (devfn < dev->devfn) {
209             n = n->rb_left;
210         } else if (devfn > dev->devfn) {
211             n = n->rb_right;
212         } else {
213             return dev;
214         }
215     }
216     
217     return NULL;
218 }
219
220
221
222
223
224
225
226 static int addr_port_read(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
227     struct pci_internal * pci_state = (struct pci_internal *)dev->private_data;
228     int reg_offset = port & 0x3;
229     uint8_t * reg_addr = ((uint8_t *)&(pci_state->addr_reg.val)) + reg_offset;
230
231     PrintDebug("Reading PCI Address Port (%x): %x len=%d\n", port, pci_state->addr_reg.val, length);
232
233     if (length == 4) {
234         if (reg_offset != 0) {
235             PrintError("Invalid Address Port Read\n");
236             return -1;
237         }
238         *(uint32_t *)dst = *(uint32_t *)reg_addr;
239     } else if (length == 2) {
240         if (reg_offset > 2) {
241             PrintError("Invalid Address Port Read\n");
242             return -1;
243         }
244         *(uint16_t *)dst = *(uint16_t *)reg_addr;
245     } else if (length == 1) {
246         *(uint8_t *)dst = *(uint8_t *)reg_addr;
247     } else {
248         PrintError("Invalid read length (%d) for PCI address register\n", length);
249         return -1;
250     }
251     
252
253     return length;
254 }
255
256
257 static int addr_port_write(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
258     struct pci_internal * pci_state = (struct pci_internal *)dev->private_data;
259     int reg_offset = port & 0x3; 
260     uint8_t * reg_addr = ((uint8_t *)&(pci_state->addr_reg.val)) + reg_offset;
261
262
263     if (length == 4) {
264         if (reg_offset != 0) {
265             PrintError("Invalid Address Port Write\n");
266             return -1;
267         }
268
269         PrintDebug("Writing PCI 4 bytes Val=%x\n",  *(uint32_t *)src);
270
271         *(uint32_t *)reg_addr = *(uint32_t *)src;
272     } else if (length == 2) {
273         if (reg_offset > 2) {
274             PrintError("Invalid Address Port Write\n");
275             return -1;
276         }
277
278         PrintDebug("Writing PCI 2 byte Val=%x\n",  *(uint16_t *)src);
279
280         *(uint16_t *)reg_addr = *(uint16_t *)src;
281     } else if (length == 1) {
282         PrintDebug("Writing PCI 1 byte Val=%x\n",  *(uint8_t *)src);
283         *(uint8_t *)reg_addr = *(uint8_t *)src;
284     } else {
285         PrintError("Invalid write length (%d) for PCI address register\n", length);
286         return -1;
287     }
288
289     PrintDebug("Writing PCI Address Port(%x): %x\n", port, pci_state->addr_reg.val);
290
291     return length;
292 }
293
294
295 static int data_port_read(ushort_t port, void * dst, uint_t length, struct vm_device * vmdev) {
296     struct pci_internal * pci_state =  (struct pci_internal *)(vmdev->private_data);
297     struct pci_device * pci_dev = NULL;
298     uint_t reg_num = (pci_state->addr_reg.reg_num << 2) + (port & 0x3);
299     int i;
300
301     if (pci_state->addr_reg.bus_num != 0) {
302         int i = 0;
303         for (i = 0; i < length; i++) {
304             *((uint8_t *)dst + i) = 0xff;
305         }
306
307         return length;
308     }
309
310     PrintDebug("Reading PCI Data register. bus = %d, dev = %d, reg = %d (%x), cfg_reg = %x\n", 
311                pci_state->addr_reg.bus_num, 
312                pci_state->addr_reg.dev_num, 
313                reg_num, reg_num, 
314                pci_state->addr_reg.val);
315
316     pci_dev = get_device(&(pci_state->bus_list[0]), pci_state->addr_reg.dev_num, pci_state->addr_reg.fn_num);
317     
318     if (pci_dev == NULL) {
319         for (i = 0; i < length; i++) {
320             *(uint8_t *)((uint8_t *)dst + i) = 0xff;
321         }
322
323         return length;
324     }
325
326     if (pci_dev->type == PCI_PASSTHROUGH) {
327         if (pci_dev->config_read(reg_num, dst, length, pci_dev->priv_data) == -1) {
328             PrintError("Failed to handle configuration update for passthrough pci_device\n");
329             return -1;
330         }
331         
332         return 0;
333     }
334
335     for (i = 0; i < length; i++) {
336         *(uint8_t *)((uint8_t *)dst + i) = pci_dev->config_space[reg_num + i];
337     }
338
339     PrintDebug("\tVal=%x, len=%d\n", *(uint32_t *)dst, length);
340
341     return length;
342 }
343
344
345 static inline int is_cfg_reg_writable(uchar_t header_type, int reg_num) {
346     if (header_type == 0x00) {
347         switch (reg_num) {
348             case 0x00:
349             case 0x01:
350             case 0x02:
351             case 0x03:
352             case 0x08:
353             case 0x09:
354             case 0x0a:
355             case 0x0b:
356             case 0x0e:
357             case 0x3d:
358                 return 0;
359                            
360            default:
361                return 1;
362  
363         }
364     } else if (header_type == 0x80) {
365         switch (reg_num) {
366             case 0x00:
367             case 0x01:
368             case 0x02:
369             case 0x03:
370             case 0x08:
371             case 0x09:
372             case 0x0a:
373             case 0x0b:
374             case 0x0e:
375             case 0x3d:
376                 return 0;
377                            
378            default:
379                return 1;
380  
381         }
382     } else {
383         // PCI to PCI Bridge = 0x01
384         // CardBus Bridge = 0x02
385
386         // huh?
387         PrintError("Invalid PCI Header type (0x%.2x)\n", header_type);
388
389         return -1;
390     }
391 }
392
393
394 static int bar_update(struct guest_info * info, struct pci_device * pci, int bar_num, uint32_t new_val) {
395     struct v3_pci_bar * bar = &(pci->bar[bar_num]);
396
397     PrintDebug("Updating BAR Register  (Dev=%s) (bar=%d) (old_val=0x%x) (new_val=0x%x)\n", 
398                pci->name, bar_num, bar->val, new_val);
399
400     switch (bar->type) {
401         case PCI_BAR_IO: {
402             int i = 0;
403
404             PrintDebug("\tRehooking %d IO ports from base 0x%x to 0x%x for %d ports\n",
405                        bar->num_ports, PCI_IO_BASE(bar->val), PCI_IO_BASE(new_val),
406                        bar->num_ports);
407                 
408             // only do this if pci device is enabled....
409             if (!(pci->config_header.status & 0x1)) {
410                 PrintError("PCI Device IO space not enabled\n");
411             }
412
413             for (i = 0; i < bar->num_ports; i++) {
414
415                 PrintDebug("Rehooking PCI IO port (old port=%u) (new port=%u)\n",  
416                            PCI_IO_BASE(bar->val) + i, PCI_IO_BASE(new_val) + i);
417
418                 v3_unhook_io_port(info, PCI_IO_BASE(bar->val) + i);
419
420                 if (v3_hook_io_port(info, PCI_IO_BASE(new_val) + i, 
421                                     bar->io_read, bar->io_write, 
422                                     bar->private_data) == -1) {
423
424                     PrintError("Could not hook PCI IO port (old port=%u) (new port=%u)\n",  
425                                PCI_IO_BASE(bar->val) + i, PCI_IO_BASE(new_val) + i);
426                     v3_print_io_map(info);
427                     return -1;
428                 }
429             }
430
431             bar->val = new_val;
432
433             break;
434         }
435         case PCI_BAR_MEM32: {
436             v3_unhook_mem(info, (addr_t)(bar->val));
437             
438             if (bar->mem_read) {
439                 v3_hook_full_mem(info, PCI_MEM32_BASE(new_val), 
440                                  PCI_MEM32_BASE(new_val) + (bar->num_pages * PAGE_SIZE_4KB),
441                                  bar->mem_read, bar->mem_write, pci->priv_data);
442             } else {
443                 PrintError("Write hooks not supported for PCI\n");
444                 return -1;
445             }
446
447             bar->val = new_val;
448
449             break;
450         }
451         case PCI_BAR_NONE: {
452             PrintDebug("Reprogramming an unsupported BAR register (Dev=%s) (bar=%d) (val=%x)\n", 
453                        pci->name, bar_num, new_val);
454             break;
455         }
456         default:
457             PrintError("Invalid Bar Reg updated (bar=%d)\n", bar_num);
458             return -1;
459     }
460
461     return 0;
462 }
463
464
465 static int data_port_write(ushort_t port, void * src, uint_t length, struct vm_device * vmdev) {
466     struct pci_internal * pci_state = (struct pci_internal *)vmdev->private_data;
467     struct pci_device * pci_dev = NULL;
468     uint_t reg_num = (pci_state->addr_reg.reg_num << 2) + (port & 0x3);
469     int i;
470
471
472     if (pci_state->addr_reg.bus_num != 0) {
473         return length;
474     }
475
476     PrintDebug("Writing PCI Data register. bus = %d, dev = %d, fn = %d, reg = %d (0x%x) addr_reg = 0x%x (val=0x%x, len=%d)\n", 
477                pci_state->addr_reg.bus_num, 
478                pci_state->addr_reg.dev_num, 
479                pci_state->addr_reg.fn_num,
480                reg_num, reg_num, 
481                pci_state->addr_reg.val,
482                *(uint32_t *)src, length);
483
484
485     pci_dev = get_device(&(pci_state->bus_list[0]), pci_state->addr_reg.dev_num, pci_state->addr_reg.fn_num);
486     
487     if (pci_dev == NULL) {
488         PrintError("Writing configuration space for non-present device (dev_num=%d)\n", 
489                    pci_state->addr_reg.dev_num); 
490         return -1;
491     }
492     
493     if (pci_dev->type == PCI_PASSTHROUGH) {
494         if (pci_dev->config_write(reg_num, src, length, pci_dev->priv_data) == -1) {
495             PrintError("Failed to handle configuration update for passthrough pci_device\n");
496             return -1;
497         }
498         
499         return 0;
500     }
501
502
503     for (i = 0; i < length; i++) {
504         uint_t cur_reg = reg_num + i;
505         int writable = is_cfg_reg_writable(pci_dev->config_header.header_type, cur_reg);
506         
507         if (writable == -1) {
508             PrintError("Invalid PCI configuration space\n");
509             return -1;
510         }
511
512         if (writable) {
513             pci_dev->config_space[cur_reg] = *(uint8_t *)((uint8_t *)src + i);
514
515             if ((cur_reg >= 0x10) && (cur_reg < 0x28)) {
516                 // BAR Register Update
517                 int bar_reg = ((cur_reg & ~0x3) - 0x10) / 4;
518                 
519                 pci_dev->bar_update_flag = 1;
520                 pci_dev->bar[bar_reg].updated = 1;
521                 
522                 // PrintDebug("Updating BAR register %d\n", bar_reg);
523
524             } else if ((cur_reg >= 0x30) && (cur_reg < 0x34)) {
525                 // Extension ROM update
526
527                 pci_dev->ext_rom_update_flag = 1;
528             } else if (cur_reg == 0x04) {
529                 // COMMAND update            
530                 uint8_t command = *((uint8_t *)src + i);
531                 
532                 PrintError("command update for %s old=%x new=%x\n",
533                            pci_dev->name, 
534                            pci_dev->config_space[cur_reg],command);
535
536                 pci_dev->config_space[cur_reg] = command;             
537
538                 if (pci_dev->cmd_update) {
539                     pci_dev->cmd_update(pci_dev, (command & 0x01), (command & 0x02));
540                 }
541                 
542             } else if (cur_reg == 0x0f) {
543                 // BIST update
544                 pci_dev->config_header.BIST = 0x00;
545             }
546         } else {
547             PrintError("PCI Write to read only register %d\n", cur_reg);
548         }
549     }
550
551     if (pci_dev->config_update) {
552         pci_dev->config_update(reg_num, src, length, pci_dev->priv_data);
553     }
554
555     // Scan for BAR updated
556     if (pci_dev->bar_update_flag) {
557         for (i = 0; i < 6; i++) {
558             if (pci_dev->bar[i].updated) {
559                 int bar_offset = 0x10 + 4 * i;
560
561
562                 if (pci_dev->bar[i].type == PCI_BAR_PASSTHROUGH) {
563                     if (pci_dev->bar[i].bar_write(i, (uint32_t *)(pci_dev->config_space + bar_offset), pci_dev->bar[i].private_data) == -1) {
564                         PrintError("Error in passthrough bar write operation\n");
565                         return -1;
566                     }
567                 } else {
568
569                     *(uint32_t *)(pci_dev->config_space + bar_offset) &= pci_dev->bar[i].mask;
570                     // check special flags....
571
572                     // bar_update
573                     if (bar_update(vmdev->vm, pci_dev, i, *(uint32_t *)(pci_dev->config_space + bar_offset)) == -1) {
574                         PrintError("PCI Device %s: Bar update Error Bar=%d\n", pci_dev->name, i);
575                         return -1;
576                     }
577                 }
578
579                 pci_dev->bar[i].updated = 0;
580             }
581         }
582         pci_dev->bar_update_flag = 0;
583     }
584
585     if ((pci_dev->ext_rom_update_flag) && (pci_dev->ext_rom_update)) {
586         pci_dev->ext_rom_update(pci_dev);
587         pci_dev->ext_rom_update_flag = 0;
588     }
589
590
591     return length;
592 }
593
594
595
596 static int pci_reset_device(struct vm_device * dev) {
597     PrintDebug("pci: reset device\n");    
598     return 0;
599 }
600
601
602 static int pci_start_device(struct vm_device * dev) {
603     PrintDebug("pci: start device\n");
604     return 0;
605 }
606
607
608 static int pci_stop_device(struct vm_device * dev) {
609     PrintDebug("pci: stop device\n");  
610     return 0;
611 }
612
613
614
615 static int pci_free(struct vm_device * dev) {
616     int i = 0;
617     
618     for (i = 0; i < 4; i++){
619         v3_dev_unhook_io(dev, CONFIG_ADDR_PORT + i);
620         v3_dev_unhook_io(dev, CONFIG_DATA_PORT + i);
621     }
622     
623     return 0;
624 }
625
626
627
628 static void init_pci_busses(struct pci_internal * pci_state) {
629     int i;
630
631     for (i = 0; i < PCI_BUS_COUNT; i++) {
632         pci_state->bus_list[i].bus_num = i;
633         pci_state->bus_list[i].devices.rb_node = NULL;
634         memset(pci_state->bus_list[i].dev_map, 0, sizeof(pci_state->bus_list[i].dev_map));
635     }
636 }
637
638
639
640
641 static struct v3_device_ops dev_ops = {
642     .free = pci_free,
643     .reset = pci_reset_device,
644     .start = pci_start_device,
645     .stop = pci_stop_device,
646 };
647
648
649
650
651 static int pci_init(struct guest_info * vm, void * cfg_data) {
652     struct pci_internal * pci_state = V3_Malloc(sizeof(struct pci_internal));
653     int i = 0;
654     
655     PrintDebug("PCI internal at %p\n",(void *)pci_state);
656     
657     struct vm_device * dev = v3_allocate_device("PCI", &dev_ops, pci_state);
658     
659     if (v3_attach_device(vm, dev) == -1) {
660         PrintError("Could not attach device %s\n", "PCI");
661         return -1;
662     }
663
664     
665     pci_state->addr_reg.val = 0; 
666     pci_state->dev_io_base = PCI_DEV_IO_PORT_BASE;
667
668     init_pci_busses(pci_state);
669     
670     PrintDebug("Sizeof config header=%d\n", (int)sizeof(struct pci_config_header));
671     
672     for (i = 0; i < 4; i++) {
673         v3_dev_hook_io(dev, CONFIG_ADDR_PORT + i, &addr_port_read, &addr_port_write);
674         v3_dev_hook_io(dev, CONFIG_DATA_PORT + i, &data_port_read, &data_port_write);
675     }
676
677     return 0;
678 }
679
680
681 device_register("PCI", pci_init)
682
683
684 static inline int init_bars(struct guest_info * info, struct pci_device * pci_dev) {
685     int i = 0;
686
687     for (i = 0; i < 6; i++) {
688         int bar_offset = 0x10 + (4 * i);
689
690         if (pci_dev->bar[i].type == PCI_BAR_IO) {
691             int j = 0;
692             pci_dev->bar[i].mask = (~((pci_dev->bar[i].num_ports) - 1)) | 0x01;
693
694             if (pci_dev->bar[i].default_base_port != 0xffff) {
695                 pci_dev->bar[i].val = pci_dev->bar[i].default_base_port & pci_dev->bar[i].mask;
696             } else {
697                 pci_dev->bar[i].val = 0;
698             }
699
700             pci_dev->bar[i].val |= 0x00000001;
701
702             for (j = 0; j < pci_dev->bar[i].num_ports; j++) {
703                 // hook IO
704                 if (pci_dev->bar[i].default_base_port != 0xffff) {
705                     if (v3_hook_io_port(info, pci_dev->bar[i].default_base_port + j,
706                                         pci_dev->bar[i].io_read, pci_dev->bar[i].io_write, 
707                                         pci_dev->bar[i].private_data) == -1) {
708                         PrintError("Could not hook default io port %x\n", pci_dev->bar[i].default_base_port + j);
709                         return -1;
710                     }
711                 }
712             }
713
714             *(uint32_t *)(pci_dev->config_space + bar_offset) = pci_dev->bar[i].val;
715
716         } else if (pci_dev->bar[i].type == PCI_BAR_MEM32) {
717             pci_dev->bar[i].mask = ~((pci_dev->bar[i].num_pages << 12) - 1);
718             pci_dev->bar[i].mask |= 0xf; // preserve the configuration flags
719
720             if (pci_dev->bar[i].default_base_addr != 0xffffffff) {
721                 pci_dev->bar[i].val = pci_dev->bar[i].default_base_addr & pci_dev->bar[i].mask;
722             } else {
723                 pci_dev->bar[i].val = 0;
724             }
725
726             // hook memory
727             if (pci_dev->bar[i].mem_read) {
728                 // full hook
729                 v3_hook_full_mem(info, pci_dev->bar[i].default_base_addr,
730                                  pci_dev->bar[i].default_base_addr + (pci_dev->bar[i].num_pages * PAGE_SIZE_4KB),
731                                  pci_dev->bar[i].mem_read, pci_dev->bar[i].mem_write, pci_dev->priv_data);
732             } else if (pci_dev->bar[i].mem_write) {
733                 // write hook
734                 PrintError("Write hooks not supported for PCI devices\n");
735                 return -1;
736                 /*
737                   v3_hook_write_mem(pci_dev->vm_dev->vm, pci_dev->bar[i].default_base_addr, 
738                   pci_dev->bar[i].default_base_addr + (pci_dev->bar[i].num_pages * PAGE_SIZE_4KB),
739                   pci_dev->bar[i].mem_write, pci_dev->vm_dev);
740                 */
741             } else {
742                 // set the prefetchable flag...
743                 pci_dev->bar[i].val |= 0x00000008;
744             }
745
746
747             *(uint32_t *)(pci_dev->config_space + bar_offset) = pci_dev->bar[i].val;
748
749         } else if (pci_dev->bar[i].type == PCI_BAR_MEM24) {
750             PrintError("16 Bit memory ranges not supported (reg: %d)\n", i);
751             return -1;
752         } else if (pci_dev->bar[i].type == PCI_BAR_NONE) {
753             pci_dev->bar[i].val = 0x00000000;
754             pci_dev->bar[i].mask = 0x00000000; // This ensures that all updates will be dropped
755             *(uint32_t *)(pci_dev->config_space + bar_offset) = pci_dev->bar[i].val;
756         } else if (pci_dev->bar[i].type == PCI_BAR_PASSTHROUGH) {
757
758             // Call the bar init function to get the local cached value
759             pci_dev->bar[i].bar_init(i, &(pci_dev->bar[i].val), pci_dev->bar[i].private_data);
760
761         } else {
762             PrintError("Invalid BAR type for bar #%d\n", i);
763             return -1;
764         }
765     }
766
767     return 0;
768 }
769
770
771 int v3_pci_set_irq_bridge(struct  vm_device * pci_bus, int bus_num, 
772                           int (*raise_pci_irq)(struct vm_device * dev, struct pci_device * pci_dev),
773                           int (*lower_pci_irq)(struct vm_device * dev, struct pci_device * pci_dev),
774                           struct vm_device * bridge_dev) {
775     struct pci_internal * pci_state = (struct pci_internal *)pci_bus->private_data;
776
777
778     pci_state->bus_list[bus_num].raise_pci_irq = raise_pci_irq;
779     pci_state->bus_list[bus_num].lower_pci_irq = lower_pci_irq;
780     pci_state->bus_list[bus_num].irq_bridge_dev = bridge_dev;
781
782     return 0;
783 }
784
785 int v3_pci_raise_irq(struct vm_device * pci_bus, int bus_num, struct pci_device * dev) {
786    struct pci_internal * pci_state = (struct pci_internal *)pci_bus->private_data;
787    struct pci_bus * bus = &(pci_state->bus_list[bus_num]);
788
789    return bus->raise_pci_irq(bus->irq_bridge_dev, dev);
790 }
791
792 int v3_pci_lower_irq(struct vm_device * pci_bus, int bus_num, struct pci_device * dev) {
793    struct pci_internal * pci_state = (struct pci_internal *)pci_bus->private_data;
794    struct pci_bus * bus = &(pci_state->bus_list[bus_num]);
795
796    return bus->lower_pci_irq(bus->irq_bridge_dev, dev);
797 }
798
799 // if dev_num == -1, auto assign 
800 struct pci_device * v3_pci_register_device(struct vm_device * pci,
801                                            pci_device_type_t dev_type, 
802                                            int bus_num,
803                                            int dev_num,
804                                            int fn_num,
805                                            const char * name,
806                                            struct v3_pci_bar * bars,
807                                            int (*config_update)(uint_t reg_num, void * src, uint_t length, void * priv_data),
808                                            int (*cmd_update)(struct pci_device *pci_dev, uchar_t io_enabled, uchar_t mem_enabled),
809                                            int (*ext_rom_update)(struct pci_device * pci_dev),
810                                            void * priv_data) {
811
812     struct pci_internal * pci_state = (struct pci_internal *)pci->private_data;
813     struct pci_bus * bus = &(pci_state->bus_list[bus_num]);
814     struct pci_device * pci_dev = NULL;
815     int i;
816
817     if (dev_num > MAX_BUS_DEVICES) {
818         PrintError("Requested Invalid device number (%d)\n", dev_num);
819         return NULL;
820     }
821
822     if (dev_num == PCI_AUTO_DEV_NUM) {
823         PrintDebug("Searching for free device number\n");
824         if ((dev_num = get_free_dev_num(bus)) == -1) {
825             PrintError("No more available PCI slots on bus %d\n", bus->bus_num);
826             return NULL;
827         }
828     }
829     
830     PrintDebug("Checking for PCI Device\n");
831
832     if (get_device(bus, dev_num, fn_num) != NULL) {
833         PrintError("PCI Device already registered at slot %d on bus %d\n", 
834                    dev_num, bus->bus_num);
835         return NULL;
836     }
837
838     
839     pci_dev = (struct pci_device *)V3_Malloc(sizeof(struct pci_device));
840
841     if (pci_dev == NULL) {
842         PrintError("Could not allocate pci device\n");
843         return NULL;
844     }
845
846     memset(pci_dev, 0, sizeof(struct pci_device));
847
848
849     pci_dev->type = dev_type;
850     
851     switch (pci_dev->type) {
852         case PCI_STD_DEVICE:
853             pci_dev->config_header.header_type = 0x00;
854             break;
855         case PCI_MULTIFUNCTION:
856             pci_dev->config_header.header_type = 0x80;
857             break;
858         default:
859             PrintError("Unhandled PCI Device Type: %d\n", dev_type);
860             return NULL;
861     }
862
863
864
865     pci_dev->bus_num = bus_num;
866     pci_dev->dev_num = dev_num;
867     pci_dev->fn_num = fn_num;
868
869     strncpy(pci_dev->name, name, sizeof(pci_dev->name));
870     pci_dev->priv_data = priv_data;
871
872     // register update callbacks
873     pci_dev->config_update = config_update;
874     pci_dev->cmd_update = cmd_update;
875     pci_dev->ext_rom_update = ext_rom_update;
876
877
878     //copy bars
879     for (i = 0; i < 6; i ++) {
880         pci_dev->bar[i].type = bars[i].type;
881         pci_dev->bar[i].private_data = bars[i].private_data;
882
883         if (pci_dev->bar[i].type == PCI_BAR_IO) {
884             pci_dev->bar[i].num_ports = bars[i].num_ports;
885
886             // This is a horrible HACK becaues the BIOS is supposed to set the PCI base ports 
887             // And if the BIOS doesn't, Linux just happily overlaps device port assignments
888             if (bars[i].default_base_port != (uint16_t)-1) {
889                 pci_dev->bar[i].default_base_port = bars[i].default_base_port;
890             } else {
891                 pci_dev->bar[i].default_base_port = pci_state->dev_io_base;
892                 pci_state->dev_io_base += ( 0x100 * ((bars[i].num_ports / 0x100) + 1) );
893             }
894
895             pci_dev->bar[i].io_read = bars[i].io_read;
896             pci_dev->bar[i].io_write = bars[i].io_write;
897         } else if (pci_dev->bar[i].type == PCI_BAR_MEM32) {
898             pci_dev->bar[i].num_pages = bars[i].num_pages;
899             pci_dev->bar[i].default_base_addr = bars[i].default_base_addr;
900             pci_dev->bar[i].mem_read = bars[i].mem_read;
901             pci_dev->bar[i].mem_write = bars[i].mem_write;
902         } else if (pci_dev->bar[i].type == PCI_BAR_PASSTHROUGH) {
903             pci_dev->bar[i].bar_init = bars[i].bar_init;
904             pci_dev->bar[i].bar_write = bars[i].bar_write;
905         } else {
906             pci_dev->bar[i].num_pages = 0;
907             pci_dev->bar[i].default_base_addr = 0;
908             pci_dev->bar[i].mem_read = NULL;
909             pci_dev->bar[i].mem_write = NULL;
910         }
911     }
912
913     if (init_bars(pci->vm, pci_dev) == -1) {
914         PrintError("could not initialize bar registers\n");
915         return NULL;
916     }
917
918     // add the device
919     add_device_to_bus(bus, pci_dev);
920
921 #ifdef CONFIG_DEBUG_PCI
922     pci_dump_state(pci_state);
923 #endif
924
925     return pci_dev;
926 }
927
928
929
930 // if dev_num == -1, auto assign 
931 struct pci_device * v3_pci_register_passthrough_device(struct vm_device * pci,
932                                                        int bus_num,
933                                                        int dev_num,
934                                                        int fn_num,
935                                                        const char * name,
936                                                        int (*config_write)(uint_t reg_num, void * src, uint_t length, void * private_data),
937                                                        int (*config_read)(uint_t reg_num, void * dst, uint_t length, void * private_data),
938                                                        void * private_data) {
939
940     struct pci_internal * pci_state = (struct pci_internal *)pci->private_data;
941     struct pci_bus * bus = &(pci_state->bus_list[bus_num]);
942     struct pci_device * pci_dev = NULL;
943
944     if (dev_num > MAX_BUS_DEVICES) {
945         PrintError("Requested Invalid device number (%d)\n", dev_num);
946         return NULL;
947     }
948
949     if (dev_num == PCI_AUTO_DEV_NUM) {
950         PrintDebug("Searching for free device number\n");
951         if ((dev_num = get_free_dev_num(bus)) == -1) {
952             PrintError("No more available PCI slots on bus %d\n", bus->bus_num);
953             return NULL;
954         }
955     }
956     
957     PrintDebug("Checking for PCI Device\n");
958
959     if (get_device(bus, dev_num, fn_num) != NULL) {
960         PrintError("PCI Device already registered at slot %d on bus %d\n", 
961                    dev_num, bus->bus_num);
962         return NULL;
963     }
964
965     
966     pci_dev = (struct pci_device *)V3_Malloc(sizeof(struct pci_device));
967
968     if (pci_dev == NULL) {
969         PrintError("Could not allocate pci device\n");
970         return NULL;
971     }
972
973     memset(pci_dev, 0, sizeof(struct pci_device));
974     
975     pci_dev->bus_num = bus_num;
976     pci_dev->dev_num = dev_num;
977     pci_dev->fn_num = fn_num;
978
979     strncpy(pci_dev->name, name, sizeof(pci_dev->name));
980     pci_dev->priv_data = private_data;
981
982     // register update callbacks
983     pci_dev->config_write = config_write;
984     pci_dev->config_read = config_read;
985
986     // add the device
987     add_device_to_bus(bus, pci_dev);
988
989 #ifdef CONFIG_DEBUG_PCI
990     pci_dump_state(pci_state);
991 #endif
992
993     return pci_dev;
994 }