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.


1e6a3a35e7f623b027d97257b9ebbcff7e60a629
[palacios.git] / palacios / src / geekos / vmm_stubs.c
1 #include <geekos/vmm_stubs.h>
2 #include <geekos/serial.h>
3 #include <palacios/vm_guest.h>
4 #include <geekos/debug.h>
5
6
7
8 static inline void VM_Out_Byte(ushort_t port, uchar_t value)
9 {
10     __asm__ __volatile__ (
11         "outb %b0, %w1"
12         :
13         : "a" (value), "Nd" (port)
14     );
15 }
16
17 /*
18  * Read a byte from an I/O port.
19  */
20 static inline uchar_t VM_In_Byte(ushort_t port)
21 {
22     uchar_t value;
23
24     __asm__ __volatile__ (
25         "inb %w1, %b0"
26         : "=a" (value)
27         : "Nd" (port)
28     );
29
30     return value;
31 }
32
33
34
35
36 void * Identity(void *addr) { return addr; };
37
38 void * Allocate_VMM_Pages(int num_pages) {
39   void * start_page = Alloc_Page();
40   //SerialPrint("Starting by Allocating Page: %x (%d of %d)\n",start_page, 1, num_pages); 
41   int i = 1;
42
43   while (i < num_pages) {
44     void * tmp_page = Alloc_Page();
45     //SerialPrint("Allocating Page: %x (%d of %d)\n",tmp_page, i+1, num_pages); 
46     
47     if (tmp_page != start_page + (PAGE_SIZE * i)) {
48       //we have to start over...;
49       while (i >= 0) {
50         Free_Page(start_page + (PAGE_SIZE * i));
51         i--;
52       }
53       start_page = Alloc_Page();
54       //SerialPrint("Starting over by Allocating Page: %x (%d of %d)\n",start_page, 1, num_pages);
55       i = 1;
56       continue;
57     }
58     i++;
59   }
60
61   return start_page;
62 }
63
64 void Free_VMM_Page(void * page) {
65   Free_Page(page);
66 }
67
68
69 void * VMM_Malloc(unsigned int size) {
70   return Malloc((unsigned long) size);
71 }
72
73
74 void VMM_Free(void * addr) {
75   Free(addr);
76 }
77
78
79
80 struct guest_info * irq_map[256];
81
82 static void pic_intr_handler(struct Interrupt_State * state) {
83   Begin_IRQ(state);
84   struct guest_info * info =   irq_map[state->intNum - 32];
85   SerialPrint("Interrupt %d (IRQ=%d)\n", state->intNum, state->intNum - 32);
86
87   if (info) {
88     info->vm_ops.raise_irq(info, state->intNum - 32);
89   } else {
90     SerialPrint("Interrupt handler error: NULL pointer found, no action taken\n");
91     End_IRQ(state);
92     return;
93   }
94
95   // End_IRQ(state);
96 }
97
98
99 int hook_irq_stub(struct guest_info * info, int irq) {
100   if (irq_map[irq]) {
101     return -1;
102   }
103
104   SerialPrint("Hooking IRQ: %d (vm=0x%x)\n", irq, info);
105   irq_map[irq] = info;
106   volatile void *foo = pic_intr_handler;
107
108   /* This is disabled for the time being */
109   foo = 0;
110
111
112   Disable_IRQ(irq);
113   Install_IRQ(irq, pic_intr_handler);
114   Enable_IRQ(irq);
115   return 0;
116 }
117
118
119 int ack_irq(int irq) {
120   End_IRQ_num(irq);
121   return 0;
122 }
123
124   
125 void Init_Stubs() {
126   memset(irq_map, 0, sizeof(struct guest_info *) * 256);
127 }
128
129
130 unsigned int get_cpu_khz() {
131   extern uint_t cpu_khz_freq;
132
133   unsigned long  print_khz = (unsigned long)(cpu_khz_freq & 0xffffffff);
134   
135   PrintBoth("Detected %lu.%lu MHz CPU\n", print_khz / 1000, print_khz % 1000);
136
137   return cpu_khz_freq;
138 }
139