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.


e40c8dddadbcfed2ba4fe5ed3a461dc67c438d9c
[palacios.git] / geekos / src / geekos / vmm_stubs.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) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
11  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20 #include <geekos/vmm_stubs.h>
21 #include <geekos/serial.h>
22 #include <geekos/debug.h>
23 #include <palacios/vmm.h>
24
25
26
27 static inline void VM_Out_Byte(ushort_t port, uchar_t value)
28 {
29     __asm__ __volatile__ (
30         "outb %b0, %w1"
31         :
32         : "a" (value), "Nd" (port)
33     );
34 }
35
36 /*
37  * Read a byte from an I/O port.
38  */
39 static inline uchar_t VM_In_Byte(ushort_t port)
40 {
41     uchar_t value;
42
43     __asm__ __volatile__ (
44         "inb %w1, %b0"
45         : "=a" (value)
46         : "Nd" (port)
47     );
48
49     return value;
50 }
51
52
53
54
55 void * Identity(void *addr) { return addr; };
56
57 void * Allocate_VMM_Pages(int num_pages) {
58   void * start_page = Alloc_Page();
59   //SerialPrint("Starting by Allocating Page: %x (%d of %d)\n",start_page, 1, num_pages); 
60   int i = 1;
61
62   while (i < num_pages) {
63     void * tmp_page = Alloc_Page();
64     //SerialPrint("Allocating Page: %x (%d of %d)\n",tmp_page, i+1, num_pages); 
65     
66     if (tmp_page != start_page + (PAGE_SIZE * i)) {
67       //we have to start over...;
68       while (i >= 0) {
69         Free_Page(start_page + (PAGE_SIZE * i));
70         i--;
71       }
72       start_page = Alloc_Page();
73       //SerialPrint("Starting over by Allocating Page: %x (%d of %d)\n",start_page, 1, num_pages);
74       i = 1;
75       continue;
76     }
77     i++;
78   }
79
80   return start_page;
81 }
82
83 void Free_VMM_Page(void * page) {
84   Free_Page(page);
85 }
86
87
88 void * VMM_Malloc(unsigned int size) {
89   return Malloc((unsigned long) size);
90 }
91
92
93 void VMM_Free(void * addr) {
94   Free(addr);
95 }
96
97
98 // This is the function the interface code should call to deliver
99 // the interrupt to the vmm for handling
100 //extern int v3_deliver_interrupt(struct guest_info * vm, struct v3_interrupt *intr);
101
102
103 struct guest_info * irq_to_guest_map[256];
104
105
106
107 void translate_intr_handler(struct Interrupt_State *state) {
108   struct v3_interrupt intr;
109
110   intr.irq = state->intNum - 32;
111   intr.error = state->errorCode;
112   intr.should_ack = 0;
113
114   //  PrintBoth("translate_intr_handler: opaque=0x%x\n",mystate.opaque);
115
116   v3_deliver_irq(irq_to_guest_map[intr.irq], &intr);
117
118   End_IRQ(state);
119
120 }
121
122
123
124 int geekos_hook_interrupt(struct guest_info * vm, unsigned int  irq)
125 {
126   if (irq_to_guest_map[irq]) { 
127     PrintBoth("Attempt to hook interrupt that is already hooked\n");
128     return -1;
129   } else {
130     PrintBoth("Hooked interrupt 0x%x with opaque 0x%x\n", irq, vm);
131     irq_to_guest_map[irq] = vm;
132   }
133
134   Disable_IRQ(irq);
135   Install_IRQ(irq, translate_intr_handler);
136   Enable_IRQ(irq);
137   return 0;
138 }
139
140
141 int ack_irq(int irq) {
142   End_IRQ_num(irq);
143   return 0;
144 }
145
146   
147 void Init_Stubs() {
148   memset(irq_to_guest_map, 0, sizeof(struct guest_info *) * 256);
149 }
150
151
152 unsigned int get_cpu_khz() {
153   extern uint_t cpu_khz_freq;
154
155   unsigned long  print_khz = (unsigned long)(cpu_khz_freq & 0xffffffff);
156   
157   PrintBoth("Detected %lu.%lu MHz CPU\n", print_khz / 1000, print_khz % 1000);
158
159   return cpu_khz_freq;
160 }
161