X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fdevices%2Fkeyboard.c;h=0c1837faf4b3ee161bf93fc9d7ffa4a102ffd2d2;hb=ffd6d915b585a4a17a2d5b081313f0968885a105;hp=e974503c823a2917de86de47fb518035235e5952;hpb=94f67717b6461df514dc225ed84f03b44c44061b;p=palacios.git diff --git a/palacios/src/devices/keyboard.c b/palacios/src/devices/keyboard.c index e974503..0c1837f 100644 --- a/palacios/src/devices/keyboard.c +++ b/palacios/src/devices/keyboard.c @@ -26,6 +26,7 @@ #include #include #include +#include #ifndef V3_CONFIG_DEBUG_KEYBOARD @@ -188,6 +189,9 @@ struct keyboard_internal { // after having a f0 sent to 60 // we wait for a new output byte on 60 GETSET_SCANCODES, + // first send ACK (0xfa) + // then wait for reception, and reset kb state + SET_DEFAULTS, } state; @@ -211,8 +215,8 @@ struct keyboard_internal { // Data for system uint8_t wrap; - int mouse_enabled; - int scancode_set; + uint8_t mouse_enabled; + uint8_t scancode_set; struct queue kbd_queue; struct queue mouse_queue; @@ -223,6 +227,9 @@ struct keyboard_internal { }; +static int keyboard_reset_device(struct keyboard_internal * kbd); + + static int update_kb_irq(struct keyboard_internal * state) { int irq_num = 0; @@ -388,7 +395,7 @@ static int key_event_handler(struct v3_vm_info * vm, #ifdef V3_CONFIG_TELEMETRY else if (evt->scan_code == 0x41) { // F7 telemetry dump - v3_print_telemetry(vm); + v3_print_global_telemetry(vm); } #endif #ifdef V3_CONFIG_SYMMOD @@ -573,7 +580,7 @@ static int mouse_write_output(struct keyboard_internal * kbd, uint8_t data) { #if KEYBOARD_DEBUG_80H -static int keyboard_write_delay(ushort_t port, void * src, uint_t length, void * priv_data) { +static int keyboard_write_delay(struct guest_info *core, ushort_t port, void * src, uint_t length, void * priv_data) { if (length == 1) { PrintDebug("keyboard: write of 0x%x to 80h\n", *((uint8_t*)src)); @@ -892,12 +899,18 @@ static int keyboard_write_output(struct guest_info * core, ushort_t port, void * break; default: PrintError("keyboard: unknown scancode set %d selected\n", data); - return -1; + ret = -1; + break; } kbd->state = NORMAL; break; + case SET_DEFAULTS: + keyboard_reset_device(kbd); + kbd->state = NORMAL; + break; + default: case NORMAL: { // command is being sent to keyboard controller @@ -942,6 +955,15 @@ static int keyboard_write_output(struct guest_info * core, ushort_t port, void * kbd->state = GETSET_SCANCODES; break; + + case 0xf6: // set defaults + // ACK command + // clear output buffer + // reset to init state + push_to_output_queue(kbd, 0xfa, COMMAND, KEYBOARD); + kbd->state = SET_DEFAULTS; + break; + case 0xfe: // resend case 0xfd: // set key type make case 0xfc: // set key typ make/break @@ -950,7 +972,7 @@ static int keyboard_write_output(struct guest_info * core, ushort_t port, void * case 0xf9: // set all make case 0xf8: // set all make/break case 0xf7: // set all typemaktic - case 0xf6: // set defaults + PrintError("keyboard: unhandled known command 0x%x on output buffer (60h)\n", data); ret = -1; break; @@ -1051,9 +1073,50 @@ static int keyboard_reset_device(struct keyboard_internal * kbd) { } +#ifdef V3_CONFIG_CHECKPOINT +static int keyboard_save(struct v3_chkpt_ctx * ctx, void * private_data) { + struct keyboard_internal * kbd = (struct keyboard_internal *)private_data; + + v3_chkpt_save_8(ctx, "CMD_REG", &(kbd->cmd.val)); + v3_chkpt_save_8(ctx, "STATUS_REG", &(kbd->status.val)); + v3_chkpt_save_8(ctx, "STATE", &(kbd->state)); + v3_chkpt_save_8(ctx, "MOUSE_STATE", &(kbd->mouse_state)); + v3_chkpt_save_8(ctx, "OUTPUT", &(kbd->output_byte)); + v3_chkpt_save_8(ctx, "INPUT", &(kbd->input_byte)); + v3_chkpt_save_8(ctx, "SCANCODE_SET", &(kbd->scancode_set)); + v3_chkpt_save_8(ctx, "MOUSE_ENABLED", &(kbd->mouse_enabled)); + + + return 0; +} + + +static int keyboard_load(struct v3_chkpt_ctx * ctx, void * private_data) { + struct keyboard_internal * kbd = (struct keyboard_internal *)private_data; + keyboard_reset_device(kbd); + + v3_chkpt_load_8(ctx, "CMD_REG", &(kbd->cmd.val)); + v3_chkpt_load_8(ctx, "STATUS_REG", &(kbd->status.val)); + v3_chkpt_load_8(ctx, "STATE", &(kbd->state)); + v3_chkpt_load_8(ctx, "MOUSE_STATE", &(kbd->mouse_state)); + v3_chkpt_load_8(ctx, "OUTPUT", &(kbd->output_byte)); + v3_chkpt_load_8(ctx, "INPUT", &(kbd->input_byte)); + v3_chkpt_load_8(ctx, "SCANCODE_SET", &(kbd->scancode_set)); + v3_chkpt_load_8(ctx, "MOUSE_ENABLED", &(kbd->mouse_enabled)); + + + return 0; +} + +#endif + + static struct v3_device_ops dev_ops = { .free = (int (*)(void *))keyboard_free, - +#ifdef V3_CONFIG_CHECKPOINT + .save = keyboard_save, + .load = keyboard_load +#endif }; @@ -1068,6 +1131,11 @@ static int keyboard_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { kbd = (struct keyboard_internal *)V3_Malloc(sizeof(struct keyboard_internal)); + if (!kbd) { + PrintError("Cannot allocate in init\n"); + return -1; + } + memset(kbd, 0, sizeof(struct keyboard_internal)); kbd->vm = vm;