1 #include <devices/keyboard.h>
3 #include <palacios/vmm.h>
4 #include <palacios/vmm_types.h>
6 #define KEYBOARD_DEBUG 1
9 #define KEYBOARD_DEBUG_PRINT(first, rest...) do { SerialPrint(first, ## rest ); } while (0)
11 #define KEYBOARD_DEBUG_PRINT(first, rest...)
15 extern struct vmm_os_hooks *os_hooks;
17 extern void SerialPrint(const char *format, ...);
21 #define KEYBOARD_DATA_REG 0x60
22 #define KEYBOARD_CONTROL_REG 0x64
24 #define KEYBOARD_IRQ 0x1
28 // The currently targetted keyboard
29 static struct vm_device *thekeyboard=NULL;
32 struct keyboard_internal {
33 // read* is what is seen when reads are done from the VM
35 uchar_t read_scancode;
36 // write* is where we put the writes from the VM
38 uchar_t write_scancode;
40 uchar_t status_byte; // for on-board uC
42 uchar_t input_queue; // input queue is for communication *to* the on-board uC
43 uint_t input_queue_len; // num items queued
44 uchar_t output_queue; // output queue is for communcation *from* the on-board uC
45 uint_t output_queue_len; // num items queued
49 static struct vm_device *demultiplex_injected_key(uchar_t status, uchar_t scancode)
51 // this currently does nothing
55 int keyboard_interrupt(uint_t irq,struct vm_device * dev);
57 void deliver_key_to_vmm(uchar_t status, uchar_t scancode)
59 struct vm_device *dev = demultiplex_injected_key(status,scancode);
61 struct keyboard_internal *state = (struct keyboard_internal *)dev->private_data;
63 KEYBOARD_DEBUG_PRINT("keyboard: injected status 0x%x, and scancode 0x%x\n", status,scancode);
65 // This is wrong - the read status should be some combination of the
66 // status/scancode within the VM, and that of the actual device
67 state->read_status=status;
68 state->read_scancode=scancode;
70 keyboard_interrupt(KEYBOARD_IRQ,dev);
74 int keyboard_reset_device(struct vm_device * dev)
76 struct keyboard_internal *data = (struct keyboard_internal *) dev->private_data;
78 memset(data,0,sizeof(struct keyboard_internal));
80 KEYBOARD_DEBUG_PRINT("keyboard: reset device\n");
90 int keyboard_start_device(struct vm_device *dev)
92 KEYBOARD_DEBUG_PRINT("keyboard: start device\n");
97 int keyboard_stop_device(struct vm_device *dev)
99 KEYBOARD_DEBUG_PRINT("keyboard: stop device\n");
106 int keyboard_write_control_port(ushort_t port,
109 struct vm_device * dev)
111 struct keyboard_internal *state = (struct keyboard_internal *) dev->private_data;
114 uchar_t data = *((uchar_t*)src);
115 KEYBOARD_DEBUG_PRINT("keyboard: write of 0x%x to control port\n",data);
116 state->write_status=data;
119 KEYBOARD_DEBUG_PRINT("keyboard: unknown size write to control port!\n");
124 int keyboard_read_control_port(ushort_t port,
127 struct vm_device * dev)
129 struct keyboard_internal *state = (struct keyboard_internal *) dev->private_data;
133 KEYBOARD_DEBUG_PRINT("keyboard: read from control port: ");
134 data=state->read_status;
135 KEYBOARD_DEBUG_PRINT("0x%x\n",data);
136 memcpy(dest,&data,length);
139 KEYBOARD_DEBUG_PRINT("keyboard: unknown size read from control port!\n");
144 int keyboard_write_data_port(ushort_t port,
147 struct vm_device * dev)
149 struct keyboard_internal *state = (struct keyboard_internal *) dev->private_data;
152 uchar_t data = *((uchar_t*)src);
153 KEYBOARD_DEBUG_PRINT("keyboard: write of 0x%x to data port\n",data);
154 state->write_scancode=data;
157 KEYBOARD_DEBUG_PRINT("keyboard: unknown size write to data port!\n");
162 int keyboard_read_data_port(ushort_t port,
165 struct vm_device * dev)
167 struct keyboard_internal *state = (struct keyboard_internal *) dev->private_data;
171 KEYBOARD_DEBUG_PRINT("keyboard: read from data port: ");
172 data=state->read_scancode;
173 KEYBOARD_DEBUG_PRINT("0x%x\n",data);
174 memcpy(dest,&data,1);
177 KEYBOARD_DEBUG_PRINT("keyboard: unknown size read from data port!\n");
183 int keyboard_interrupt(uint_t irq,
184 struct vm_device * dev)
186 KEYBOARD_DEBUG_PRINT("keyboard: interrupt\n");
188 dev->vm->vm_ops.raise_irq(dev->vm,irq,0);
195 int keyboard_init_device(struct vm_device * dev)
198 // struct keyboard_internal *data = (struct keyboard_internal *) dev->private_data;
200 KEYBOARD_DEBUG_PRINT("keyboard: init_device\n");
202 // Would read state here
204 keyboard_reset_device(dev);
207 dev_hook_io(dev, KEYBOARD_DATA_REG, &keyboard_read_data_port, &keyboard_write_data_port);
208 dev_hook_io(dev, KEYBOARD_CONTROL_REG, &keyboard_read_control_port, &keyboard_write_control_port);
211 // We do not hook the IRQ here. Instead, the underlying device driver
212 // is responsible to call us back
218 int keyboard_deinit_device(struct vm_device *dev)
221 dev_unhook_io(dev, KEYBOARD_DATA_REG);
222 dev_unhook_io(dev, KEYBOARD_CONTROL_REG);
224 keyboard_reset_device(dev);
232 static struct vm_device_ops dev_ops = {
233 .init = keyboard_init_device,
234 .deinit = keyboard_deinit_device,
235 .reset = keyboard_reset_device,
236 .start = keyboard_start_device,
237 .stop = keyboard_stop_device,
243 struct vm_device *create_keyboard() {
245 if (thekeyboard!=NULL) {
246 KEYBOARD_DEBUG_PRINT("keyboard: creating >1 keyboard device. This will probably fail!\n");
249 struct keyboard_internal * keyboard_state = os_hooks->malloc(sizeof(struct keyboard_internal));
251 struct vm_device *device = create_device("KEYBOARD", &dev_ops, keyboard_state);