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.


Release 1.0
[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 #include <palacios/vmm_host_events.h>
25
26
27 struct guest_info * g_vm_guest = NULL;
28
29
30 // This is the function the interface code should call to deliver
31 // the interrupt to the vmm for handling
32 //extern int v3_deliver_interrupt(struct guest_info * vm, struct v3_interrupt *intr);
33
34
35 struct guest_info * irq_to_guest_map[256];
36
37
38
39
40 static inline void VM_Out_Byte(ushort_t port, uchar_t value)
41 {
42     __asm__ __volatile__ (
43         "outb %b0, %w1"
44         :
45         : "a" (value), "Nd" (port)
46     );
47 }
48
49 /*
50  * Read a byte from an I/O port.
51  */
52 static inline uchar_t VM_In_Byte(ushort_t port)
53 {
54     uchar_t value;
55
56     __asm__ __volatile__ (
57         "inb %w1, %b0"
58         : "=a" (value)
59         : "Nd" (port)
60     );
61
62     return value;
63 }
64
65
66
67 void Init_Stubs(struct guest_info * info) {
68   memset(irq_to_guest_map, 0, sizeof(struct guest_info *) * 256);
69   g_vm_guest = info;
70 }
71
72
73
74 void * Identity(void *addr) { return addr; };
75
76 void * Allocate_VMM_Pages(int num_pages) {
77   void * start_page = Alloc_Page();
78   //SerialPrint("Starting by Allocating Page: %x (%d of %d)\n",start_page, 1, num_pages); 
79   int i = 1;
80
81   while (i < num_pages) {
82     void * tmp_page = Alloc_Page();
83     //SerialPrint("Allocating Page: %x (%d of %d)\n",tmp_page, i+1, num_pages); 
84     
85     if (tmp_page != start_page + (PAGE_SIZE * i)) {
86       //we have to start over...;
87       while (i >= 0) {
88         Free_Page(start_page + (PAGE_SIZE * i));
89         i--;
90       }
91       start_page = Alloc_Page();
92       //SerialPrint("Starting over by Allocating Page: %x (%d of %d)\n",start_page, 1, num_pages);
93       i = 1;
94       continue;
95     }
96     i++;
97   }
98
99   return start_page;
100 }
101
102 void Free_VMM_Page(void * page) {
103   Free_Page(page);
104 }
105
106
107 void * VMM_Malloc(unsigned int size) {
108   return Malloc((unsigned long) size);
109 }
110
111
112 void VMM_Free(void * addr) {
113   Free(addr);
114 }
115
116
117
118 void send_key_to_vmm(unsigned char status, unsigned char scancode) {
119   struct v3_keyboard_event evt;
120
121   evt.status = status;
122   evt.scan_code = scancode;
123
124   if (g_vm_guest) {
125     v3_deliver_keyboard_event(g_vm_guest, &evt);
126   }
127 }
128
129
130 void send_mouse_to_vmm(unsigned char packet[3]) {
131   struct v3_mouse_event evt;
132
133   memcpy(evt.data, packet, 3);
134
135   if (g_vm_guest) {
136     v3_deliver_mouse_event(g_vm_guest, &evt);
137   }
138 }
139
140 void send_tick_to_vmm(unsigned int period_us) {
141   struct v3_timer_event evt;
142
143   evt.period_us = period_us;
144
145   if (g_vm_guest) {
146     v3_deliver_timer_event(g_vm_guest, &evt);
147   }
148 }
149
150
151 void translate_intr_handler(struct Interrupt_State *state) {
152   struct v3_interrupt intr;
153
154   intr.irq = state->intNum - 32;
155   intr.error = state->errorCode;
156   intr.should_ack = 0;
157
158   //  PrintBoth("translate_intr_handler: opaque=0x%x\n",mystate.opaque);
159
160   v3_deliver_irq(irq_to_guest_map[intr.irq], &intr);
161
162   End_IRQ(state);
163
164 }
165
166
167
168 int geekos_hook_interrupt(struct guest_info * vm, unsigned int  irq)
169 {
170   if (irq_to_guest_map[irq]) { 
171     PrintBoth("Attempt to hook interrupt that is already hooked\n");
172     return -1;
173   } else {
174     PrintBoth("Hooked interrupt 0x%x with opaque 0x%x\n", irq, vm);
175     irq_to_guest_map[irq] = vm;
176   }
177
178   Disable_IRQ(irq);
179   Install_IRQ(irq, translate_intr_handler);
180   Enable_IRQ(irq);
181   return 0;
182 }
183
184
185 int ack_irq(int irq) {
186   End_IRQ_num(irq);
187   return 0;
188 }
189
190   
191
192
193 unsigned int get_cpu_khz() {
194   extern uint_t cpu_khz_freq;
195
196   unsigned long  print_khz = (unsigned long)(cpu_khz_freq & 0xffffffff);
197   
198   PrintBoth("Detected %lu.%lu MHz CPU\n", print_khz / 1000, print_khz % 1000);
199
200   return cpu_khz_freq;
201 }
202
203