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.


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