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.


fixed a ton of compile errors
[palacios.git] / palacios / src / palacios / vmm_intr.c
1 #include <palacios/vmm_intr.h>
2 #include <palacios/vmm.h>
3
4 #include <palacios/vm_guest.h>
5
6 #ifndef DEBUG_INTERRUPTS
7 #undef PrintDebug
8 #define PrintDebug(fmt, args...)
9 #endif
10
11
12
13 /*Zheng 07/30/2008*/
14 void init_interrupt_state(struct guest_info * info) {
15   info->intr_state.excp_pending = 0;
16   info->intr_state.excp_num = 0;
17   info->intr_state.excp_error_code = 0;
18
19   info->vm_ops.raise_irq = &v3_raise_irq;
20   info->vm_ops.lower_irq = &v3_lower_irq; //Zheng added
21 }
22
23 void set_intr_controller(struct guest_info * info, struct intr_ctrl_ops * ops, void * state) {
24   info->intr_state.controller = ops;
25   info->intr_state.controller_state = state;
26 }
27
28
29
30 // This structure is used to dispatch
31 // interrupts delivered to vmm via deliver interrupt to vmm 
32 // it is what we put into the opaque field given to 
33 // the host os when we install the handler
34 struct vmm_intr_decode { 
35   void              (*handler)(struct vmm_intr_state *state);
36   // This opaque is user supplied by the caller
37   // of hook_irq_new
38   void              *opaque;
39 };
40
41 int v3_hook_irq(uint_t irq,
42              void (*handler)(struct vmm_intr_state *state),
43              void  *opaque)
44 {
45   struct vmm_intr_decode *d = (struct vmm_intr_decode *)V3_Malloc(sizeof(struct vmm_intr_decode));
46
47   if (!d) { return -1; }
48
49   d->handler = handler;
50   d->opaque = opaque;
51   
52   if (V3_Hook_Interrupt(irq,d)) { 
53     PrintError("hook_irq: failed to hook irq 0x%x to decode 0x%x\n", irq,d);
54     return -1;
55   } else {
56     PrintDebug("hook_irq: hooked irq 0x%x to decode 0x%x\n", irq,d);
57     return 0;
58   }
59 }
60
61
62 void deliver_interrupt_to_vmm(struct vmm_intr_state *state)
63 {
64
65   PrintDebug("deliver_interrupt_to_vmm: state=0x%x\n",state);
66
67   struct vmm_intr_decode *d = (struct vmm_intr_decode *)(state->opaque);
68   
69   void *temp = state->opaque;
70   state->opaque = d->opaque;
71
72   d->handler(state);
73   
74   state->opaque=temp;
75 }
76
77
78 static void guest_injection_irq_handler(struct vmm_intr_state *state)
79 {
80   struct guest_info *guest = (struct guest_info *)(state->opaque);
81   PrintDebug("[guest_injection_irq_handler] raise_irq=0x%x (guest=0x%x)\n", state->irq, guest);
82   PrintDebug("guest_irq_injection: state=0x%x\n", state);
83   guest->vm_ops.raise_irq(guest,state->irq);
84 }
85
86
87 int v3_hook_irq_for_guest_injection(struct guest_info *info, int irq)
88 {
89
90   int rc = v3_hook_irq(irq,
91                        guest_injection_irq_handler,
92                        info);
93
94   if (rc) { 
95     PrintError("guest_irq_injection: failed to hook irq 0x%x (guest=0x%x)\n", irq, info);
96     return -1;
97   } else {
98     PrintDebug("guest_irq_injection: hooked irq 0x%x (guest=0x%x)\n", irq, info);
99     return 0;
100   }
101 }
102
103
104
105
106 int v3_raise_exception_with_error(struct guest_info * info, uint_t excp, uint_t error_code) {
107   struct vm_intr * intr_state = &(info->intr_state);
108
109   if (intr_state->excp_pending == 0) {
110     intr_state->excp_pending = 1;
111     intr_state->excp_num = excp;
112     intr_state->excp_error_code = error_code;
113     intr_state->excp_error_code_valid = 1;
114     PrintDebug("[v3_raise_exception_with_error] error code: %x\n", error_code);
115   } else {
116     PrintError("exception already pending, currently not implemented\n");
117     return -1;
118   }
119
120   return 0;
121 }
122
123 int v3_raise_exception(struct guest_info * info, uint_t excp) {
124   struct vm_intr * intr_state = &(info->intr_state);
125   PrintDebug("[v3_raise_exception]\n");
126   if (intr_state->excp_pending == 0) {
127     intr_state->excp_pending = 1;
128     intr_state->excp_num = excp;
129     intr_state->excp_error_code = 0;
130     intr_state->excp_error_code_valid = 0;
131   } else {
132     PrintError("exception already pending, currently not implemented\n");
133     return -1;
134   }
135
136   return 0;
137 }
138
139 /*Zheng 07/30/2008*/
140
141 int v3_lower_irq(struct guest_info * info, int irq) {
142   // Look up PIC and resend
143   V3_ASSERT(info);
144   V3_ASSERT(info->intr_state.controller);
145   V3_ASSERT(info->intr_state.controller->raise_intr);
146
147   PrintDebug("[v3_lower_irq]\n");
148
149   //  if ((info->intr_state.controller) && 
150   //  (info->intr_state.controller->raise_intr)) {
151     info->intr_state.controller->lower_intr(info->intr_state.controller_state, irq);
152     //} else {
153     // PrintDebug("There is no registered Interrupt Controller... (NULL POINTER)\n");
154     // return -1;
155     //}
156   return 0;
157 }
158
159 int v3_raise_irq(struct guest_info * info, int irq) {
160   // Look up PIC and resend
161   V3_ASSERT(info);
162   V3_ASSERT(info->intr_state.controller);
163   V3_ASSERT(info->intr_state.controller->raise_intr);
164
165   PrintDebug("[v3_raise_irq]\n");
166
167   //  if ((info->intr_state.controller) && 
168   //  (info->intr_state.controller->raise_intr)) {
169     info->intr_state.controller->raise_intr(info->intr_state.controller_state, irq);
170     //} else {
171     // PrintDebug("There is no registered Interrupt Controller... (NULL POINTER)\n");
172     // return -1;
173     //}
174   return 0;
175 }
176
177  
178
179 int intr_pending(struct guest_info * info) {
180   struct vm_intr * intr_state = &(info->intr_state);
181
182   //  PrintDebug("[intr_pending]\n");
183   if (intr_state->excp_pending == 1) {
184     return 1;
185   } else if (intr_state->controller->intr_pending(intr_state->controller_state) == 1) {
186     return 1;
187   }
188
189   /* Check [A]PIC */
190
191   return 0;
192 }
193
194
195 uint_t get_intr_number(struct guest_info * info) {
196   struct vm_intr * intr_state = &(info->intr_state);
197
198   if (intr_state->excp_pending == 1) {
199     return intr_state->excp_num;
200   } else if (intr_state->controller->intr_pending(intr_state->controller_state)) {
201     PrintDebug("[get_intr_number] intr_number = %d\n", intr_state->controller->get_intr_number(intr_state->controller_state));
202     return intr_state->controller->get_intr_number(intr_state->controller_state);
203   }
204
205   /* someway to get the [A]PIC intr */
206
207   return 0;
208 }
209
210
211 intr_type_t get_intr_type(struct guest_info * info) {
212  struct vm_intr * intr_state = &(info->intr_state);
213
214   if (intr_state->excp_pending) {
215     PrintDebug("[get_intr_type] Exception\n");
216     return EXCEPTION;
217   } else if (intr_state->controller->intr_pending(intr_state->controller_state)) {
218     PrintDebug("[get_intr_type] External_irq\n");
219     return EXTERNAL_IRQ;
220   }
221     PrintDebug("[get_intr_type] Invalid_Intr\n");
222   return INVALID_INTR;
223 }
224
225
226
227
228
229
230 int injecting_intr(struct guest_info * info, uint_t intr_num, intr_type_t type) {
231   struct vm_intr * intr_state = &(info->intr_state);
232
233   if (type == EXCEPTION) {
234     PrintDebug("[injecting_intr] Exception\n");
235     intr_state->excp_pending = 0;
236     intr_state->excp_num = 0;
237     intr_state->excp_error_code = 0;
238     intr_state->excp_error_code_valid = 0;
239     
240   } else if (type == EXTERNAL_IRQ) {
241     PrintDebug("[injecting_intr] External_Irq with intr_num = %x\n", intr_num);
242     return intr_state->controller->begin_irq(intr_state->controller_state, intr_num);
243   }
244
245   return 0;
246 }