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.


Added generic device, some keyboard fixes (still in progress)
[palacios.git] / palacios / src / devices / generic.c
1 #include <devices/generic.h>
2 #include <geekos/io.h>
3 #include <palacios/vmm.h>
4 #include <palacios/vmm_types.h>
5
6
7
8 #define GENERIC_DEBUG 1
9
10 #if GENERIC_DEBUG
11 #define GENERIC_DEBUG_PRINT(first, rest...) do { SerialPrint(first, ## rest ); } while (0) 
12 #else
13 #define GENERIC_DEBUG_PRINT(first, rest...)
14 #endif
15
16
17 #define PORT_HOOKS 1
18 #define MEM_HOOKS  0   // not yet implmented in device model
19 #define IRQ_HOOKS  0   // not yet implemented in device model
20
21 extern struct vmm_os_hooks *os_hooks;
22
23 extern void SerialPrint(const char *format, ...);
24
25
26
27 struct generic_internal {
28   generic_port_range_type    *port_ranges;
29   uint_t                     num_port_ranges;
30   generic_address_range_type *address_ranges;
31   uint_t                     num_address_ranges;
32   generic_irq_range_type     *irq_ranges;
33   uint_t                     num_irq_ranges;
34 };
35
36
37   
38     
39
40
41
42
43 int generic_reset_device(struct vm_device * dev)
44 {
45   GENERIC_DEBUG_PRINT("generic: reset device\n");
46  
47   return 0;
48
49 }
50
51
52
53
54
55 int generic_start_device(struct vm_device *dev)
56 {
57   GENERIC_DEBUG_PRINT("generic: start device\n");
58   return 0;
59 }
60
61
62 int generic_stop_device(struct vm_device *dev)
63 {
64   GENERIC_DEBUG_PRINT("generic: stop device\n");
65   return 0;
66 }
67
68
69
70
71 int generic_write_port(ushort_t port,
72                        void * src, 
73                        uint_t length,
74                        struct vm_device * dev)
75 {
76   uint_t i;
77
78   GENERIC_DEBUG_PRINT("generic: writing 0x");
79   for (i=0;i<length;i++) { 
80     GENERIC_DEBUG_PRINT("%x",((uchar_t*)src)[i]);
81   }
82   GENERIC_DEBUG_PRINT(" to port 0x%x ... ",port);
83   for (i=0;i<length;i++) { 
84     Out_Byte(port,((uchar_t*)src)[i]);
85   }
86   GENERIC_DEBUG_PRINT(" done\n");
87   
88   return length;
89 }
90
91 int generic_read_port(ushort_t port,
92                       void * src, 
93                       uint_t length,
94                       struct vm_device * dev)
95 {
96   uint_t i;
97
98   GENERIC_DEBUG_PRINT("generic: reading 0x%x bytes from port 0x%x ...",length,port);
99   for (i=0;i<length;i++) { 
100     ((uchar_t*)src)[i] =In_Byte(port);
101   }
102   GENERIC_DEBUG_PRINT(" done ... read 0x");
103   for (i=0;i<length;i++) { 
104     GENERIC_DEBUG_PRINT("%x",((uchar_t*)src)[i]);
105   }
106   GENERIC_DEBUG_PRINT("\n");
107
108   return length;
109 }
110
111
112
113 int generic_interrupt(uint_t irq,
114                       struct vm_device * dev) 
115 {
116   PrintDebug("generic: interrupt 0x%x - injecting into VM\n",irq);
117
118   dev->vm->vm_ops.raise_irq(dev->vm,irq,0);
119
120   return 0;
121
122 }
123
124
125 int generic_init_device(struct vm_device * dev) 
126 {
127   struct generic_internal *state = (struct generic_internal *) dev->private_data;
128   uint_t i,j;
129
130   GENERIC_DEBUG_PRINT("generic: init_device\n");
131
132   // Would read state here
133
134   generic_reset_device(dev);
135
136   for (i=0;i<state->num_port_ranges;i++) { 
137     GENERIC_DEBUG_PRINT("generic: hooking ports 0x%x to 0x%x\n",state->port_ranges[i][0],state->port_ranges[i][1]);
138 #if PORT_HOOKS
139     for (j=state->port_ranges[i][0]; j<=state->port_ranges[i][1];j++) { 
140       if (dev_hook_io(dev, j, &generic_read_port, &generic_write_port)) { 
141         GENERIC_DEBUG_PRINT("generic: can't hook port 0x%x (already hooked?)\n",j);
142       }
143     }
144 #else
145     GENERIC_DEBUG_PRINT("generic: hooking ports not supported\n");
146 #endif
147
148   }
149
150   for (i=0;i<state->num_address_ranges;i++) { 
151     GENERIC_DEBUG_PRINT("generic: hooking addresses 0x%x to 0x%x\n",state->address_ranges[i][0],state->address_ranges[i][1]); 
152 #if MEM_HOOKS
153     if (dev_hook_mem(dev, state->address_ranges[i][0],state->address_ranges[i][1])) {
154       GENERIC_DEBUG_PRINT("generic: Can't hook addresses 0x%x to 0x%x (already hooked?)\n",
155                   state->address_ranges[i][0],state->address_ranges[i][1]); 
156     }
157 #else
158     GENERIC_DEBUG_PRINT("generic: hooking addresses not supported\n");
159 #endif
160
161   }
162
163   for (i=0;i<state->num_irq_ranges;i++) { 
164     GENERIC_DEBUG_PRINT("generic: hooking irqs 0x%x to 0x%x\n",state->irq_ranges[i][0],state->irq_ranges[i][1]);
165 #if IRQ_HOOKS
166     for (j=state->irq_ranges[i][0]; j<=state->irq_ranges[i][1];j++) { 
167       if (dev_hook_irq(dev, j,  &generic_interrupt)) { 
168         GENERIC_DEBUG_PRINT("generic: can't hook irq  0x%x (already hooked?)\n",j);
169       }
170     }
171 #else
172     GENERIC_DEBUG_PRINT("generic: hooking irqs not supported\n");
173 #endif
174   }
175
176   return 0;
177 }
178
179 int generic_deinit_device(struct vm_device *dev)
180 {
181   struct generic_internal *state = (struct generic_internal *) dev->private_data;
182   uint_t i,j;
183
184   GENERIC_DEBUG_PRINT("generic: deinit_device\n");
185
186   for (i=0;i<state->num_irq_ranges;i++) { 
187     GENERIC_DEBUG_PRINT("generic: unhooking irqs 0x%x to 0x%x\n",state->irq_ranges[i][0],state->irq_ranges[i][1]);
188 #if IRQ_HOOKS
189     for (j=state->irq_ranges[i][0]; j<=state->irq_ranges[i][1];j++) { 
190       if (dev_unhook_irq(dev, j)) {
191         GENERIC_DEBUG_PRINT("generic: can't unhook irq 0x%x (already unhooked?)\n",j);
192       }
193     }
194 #else
195     GENERIC_DEBUG_PRINT("generic: unhooking irqs not supported\n");
196 #endif
197
198   }
199
200   for (i=0;i<state->num_address_ranges;i++) { 
201     GENERIC_DEBUG_PRINT("generic: unhooking addresses 0x%x to 0x%x\n",state->address_ranges[i][0],state->address_ranges[i][1]); 
202 #if MEM_HOOKS
203     if (dev_unhook_mem(dev, state->address_ranges[i][0],state->address_ranges[i][1])) {
204       GENERIC_DEBUG_PRINT("generic: Can't unhook addresses 0x%x to 0x%x (already unhooked?)\n",
205                   state->address_ranges[i][0],state->address_ranges[i][1]); 
206     }
207 #else
208     GENERIC_DEBUG_PRINT("generic: unhooking addresses not supported\n");
209 #endif
210   }
211
212   for (i=0;i<state->num_port_ranges;i++) { 
213     GENERIC_DEBUG_PRINT("generic: unhooking ports 0x%x to 0x%x\n",state->port_ranges[i][0],state->port_ranges[i][1]);
214 #if PORT_HOOKS
215     for (j=state->port_ranges[i][0]; j<=state->port_ranges[i][1];j++) { 
216       if (dev_unhook_io(dev, j)) {
217         GENERIC_DEBUG_PRINT("generic: can't unhook port 0x%x (already unhooked?)\n",j);
218       }
219     }
220 #else
221     GENERIC_DEBUG_PRINT("generic: unhooking ports not supported\n");
222 #endif
223
224   }
225
226   generic_reset_device(dev);
227   return 0;
228 }
229
230
231
232
233
234 static struct vm_device_ops dev_ops = { 
235   .init = generic_init_device, 
236   .deinit = generic_deinit_device,
237   .reset = generic_reset_device,
238   .start = generic_start_device,
239   .stop = generic_stop_device,
240 };
241
242
243
244
245 struct vm_device *create_generic(generic_port_range_type    port_ranges[], 
246                                  uint_t                     num_port_ranges,
247                                  generic_address_range_type address_ranges[],
248                                  uint_t                     num_address_ranges,
249                                  generic_irq_range_type     irq_ranges[],
250                                  uint_t                     num_irq_ranges)
251 {
252   struct generic_internal * generic_state = os_hooks->malloc(sizeof(struct generic_internal));
253
254
255   generic_state->num_port_ranges=num_port_ranges;
256   if (num_port_ranges>0) { 
257     generic_state->port_ranges = os_hooks->malloc(sizeof(generic_address_range_type)*num_port_ranges);
258     memcpy(generic_state->port_ranges,port_ranges,sizeof(generic_port_range_type)*num_port_ranges);
259   } else {
260     generic_state->port_ranges=NULL;
261   }
262
263   generic_state->num_address_ranges=num_address_ranges;
264   if (num_address_ranges>0) { 
265     generic_state->address_ranges = os_hooks->malloc(sizeof(generic_address_range_type)*num_address_ranges);
266     memcpy(generic_state->address_ranges,address_ranges,sizeof(generic_address_range_type)*num_address_ranges);
267   } else {
268     generic_state->address_ranges=NULL;
269   }
270   generic_state->num_irq_ranges=num_irq_ranges;
271   if (num_irq_ranges>0) { 
272     generic_state->irq_ranges = os_hooks->malloc(sizeof(generic_address_range_type)*num_irq_ranges);
273     memcpy(generic_state->irq_ranges,irq_ranges,sizeof(generic_irq_range_type)*num_port_ranges);
274   } else {
275     generic_state->irq_ranges=NULL;
276   }
277
278
279   struct vm_device *device = create_device("GENERIC", &dev_ops, generic_state);
280
281   return device;
282 }