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 / keyboard.c
1 #include <devices/keyboard.h>
2 #include <geekos/io.h>
3 #include <palacios/vmm.h>
4 #include <palacios/vmm_types.h>
5
6 #define KEYBOARD_DEBUG 1
7
8 #if KEYBOARD_DEBUG
9 #define KEYBOARD_DEBUG_PRINT(first, rest...) PrintDebug(first, ##rest)
10 #else
11 #define KEYBOARD_DEBUG_PRINT(first, rest...)
12 #endif
13
14
15 #define KEYBOARD_DATA_REG          0x60
16 #define KEYBOARD_CONTROL_REG       0x64
17
18 #define KEYBOARD_IRQ    0x1
19
20
21
22 // The currently targetted keyboard
23 static struct vm_device *thekeyboard=NULL;
24
25
26 struct keyboard_internal {
27   // read* is what is seen when reads are done from the VM
28   uchar_t read_status;
29   uchar_t read_scancode;
30   // write* is where we put the writes from the VM
31   uchar_t write_status;
32   uchar_t write_scancode;
33
34   uchar_t status_byte;      //  for on-board uC
35
36   uchar_t input_queue;      //  input queue is for communication *to* the on-board uC
37   uint_t  input_queue_len;  //  num items queued
38   uchar_t output_queue;     //  output queue is for communcation *from* the on-board uC
39   uint_t  output_queue_len; //  num items queued 
40 };
41
42
43 static struct vm_device *demultiplex_injected_key(uchar_t status, uchar_t scancode)
44 {
45   // this currently does nothing
46   return thekeyboard;
47 }
48
49 int keyboard_interrupt(uint_t irq,struct vm_device * dev);
50
51 void deliver_key_to_vmm(uchar_t status, uchar_t scancode)
52 {
53   struct vm_device *dev = demultiplex_injected_key(status,scancode);
54
55   struct keyboard_internal *state = (struct keyboard_internal *)dev->private_data;
56
57   KEYBOARD_DEBUG_PRINT("keyboard: injected status 0x%x, and scancode 0x%x\n", status,scancode);
58   
59   // This is wrong - the read status should be some combination of the 
60   // status/scancode within the VM, and that of the actual device
61   state->read_status=status;
62   state->read_scancode=scancode;
63
64   keyboard_interrupt(KEYBOARD_IRQ,dev);
65
66 }
67
68 int keyboard_reset_device(struct vm_device * dev)
69 {
70   struct keyboard_internal *data = (struct keyboard_internal *) dev->private_data;
71   
72   memset(data,0,sizeof(struct keyboard_internal));
73   
74   KEYBOARD_DEBUG_PRINT("keyboard: reset device\n");
75  
76   return 0;
77
78 }
79
80
81
82
83
84 int keyboard_start_device(struct vm_device *dev)
85 {
86   KEYBOARD_DEBUG_PRINT("keyboard: start device\n");
87   return 0;
88 }
89
90
91 int keyboard_stop_device(struct vm_device *dev)
92 {
93   KEYBOARD_DEBUG_PRINT("keyboard: stop device\n");
94   return 0;
95 }
96
97
98
99
100 int keyboard_write_control_port(ushort_t port,
101                                 void * src, 
102                                 uint_t length,
103                                 struct vm_device * dev)
104 {
105   struct keyboard_internal *state = (struct keyboard_internal *) dev->private_data;
106
107   if (length==1) { 
108     uchar_t data = *((uchar_t*)src); 
109     KEYBOARD_DEBUG_PRINT("keyboard: write of 0x%x to control port\n",data);
110     state->write_status=data;
111     return 1;
112   } else {
113     KEYBOARD_DEBUG_PRINT("keyboard: unknown size write to control port!\n");
114     return -1;
115   }
116 }
117
118 int keyboard_read_control_port(ushort_t port,
119                                void * dest, 
120                                uint_t length,
121                                struct vm_device * dev)
122 {
123   struct keyboard_internal *state = (struct keyboard_internal *) dev->private_data;
124
125   if (length==1) { 
126     uchar_t data;
127     KEYBOARD_DEBUG_PRINT("keyboard: read from control port: ");
128     data=state->read_status;
129     KEYBOARD_DEBUG_PRINT("0x%x\n",data);
130     memcpy(dest,&data,length);
131     return 1;
132   } else {
133     KEYBOARD_DEBUG_PRINT("keyboard: unknown size read from control port!\n");
134     return -1;
135   }
136 }
137
138 int keyboard_write_data_port(ushort_t port,
139                              void * src, 
140                              uint_t length,
141                              struct vm_device * dev)
142 {
143   struct keyboard_internal *state = (struct keyboard_internal *) dev->private_data;
144
145   if (length==1) { 
146     uchar_t data = *((uchar_t*)src); 
147     KEYBOARD_DEBUG_PRINT("keyboard: write of 0x%x to data port\n",data);
148     state->write_scancode=data;
149     return 1;
150   } else {
151     KEYBOARD_DEBUG_PRINT("keyboard: unknown size write to data port!\n");
152     return -1;
153   }
154 }
155
156 int keyboard_read_data_port(ushort_t port,
157                             void * dest, 
158                             uint_t length,
159                             struct vm_device * dev)
160 {
161   struct keyboard_internal *state = (struct keyboard_internal *) dev->private_data;
162
163   if (length==1) { 
164     uchar_t data;
165     KEYBOARD_DEBUG_PRINT("keyboard: read from data port: ");
166     data=state->read_scancode;
167     KEYBOARD_DEBUG_PRINT("0x%x\n",data);
168     memcpy(dest,&data,1);
169     return 1;
170   } else {
171     KEYBOARD_DEBUG_PRINT("keyboard: unknown size read from data port!\n");
172     return -1;
173   }
174 }
175
176
177 int keyboard_interrupt(uint_t irq,
178                        struct vm_device * dev) 
179 {
180   KEYBOARD_DEBUG_PRINT("keyboard: interrupt\n");
181
182   dev->vm->vm_ops.raise_irq(dev->vm,irq);
183
184   return 0;
185
186 }
187
188
189 int keyboard_init_device(struct vm_device * dev) 
190 {
191  
192   //  struct keyboard_internal *data = (struct keyboard_internal *) dev->private_data;
193
194   KEYBOARD_DEBUG_PRINT("keyboard: init_device\n");
195
196   // Would read state here
197
198   keyboard_reset_device(dev);
199
200   // hook ports
201   dev_hook_io(dev, KEYBOARD_DATA_REG, &keyboard_read_data_port, &keyboard_write_data_port);
202   dev_hook_io(dev, KEYBOARD_CONTROL_REG, &keyboard_read_control_port, &keyboard_write_control_port);
203   
204   //
205   // We do not hook the IRQ here.  Instead, the underlying device driver
206   // is responsible to call us back
207   // 
208
209   return 0;
210 }
211
212 int keyboard_deinit_device(struct vm_device *dev)
213 {
214
215   dev_unhook_io(dev, KEYBOARD_DATA_REG);
216   dev_unhook_io(dev, KEYBOARD_CONTROL_REG);
217
218   keyboard_reset_device(dev);
219   return 0;
220 }
221
222
223
224
225
226 static struct vm_device_ops dev_ops = { 
227   .init = keyboard_init_device, 
228   .deinit = keyboard_deinit_device,
229   .reset = keyboard_reset_device,
230   .start = keyboard_start_device,
231   .stop = keyboard_stop_device,
232 };
233
234
235
236
237 struct vm_device *create_keyboard() {
238   
239   if (thekeyboard!=NULL) { 
240     KEYBOARD_DEBUG_PRINT("keyboard: creating >1 keyboard device.  This will probably fail!\n");
241   }
242   
243   struct keyboard_internal * keyboard_state = (struct keyboard_internal *)V3_Malloc(sizeof(struct keyboard_internal));
244
245   struct vm_device *device = create_device("KEYBOARD", &dev_ops, keyboard_state);
246
247   thekeyboard=device;
248   
249   return device;
250 }