X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fdevices%2Fcurses_cons.c;h=8824447932c4c74c03903c6e4b0709bd75978efb;hb=4b7f19c51325601d7e7569e6101c7bfcdf984ef7;hp=aa85972a270670e00a38cc5083c32d8853435ff7;hpb=5b1f618cf74dbcd7e490fa3fe4da5a4c53d79b5d;p=palacios.git diff --git a/palacios/src/devices/curses_cons.c b/palacios/src/devices/curses_cons.c index aa85972..8824447 100644 --- a/palacios/src/devices/curses_cons.c +++ b/palacios/src/devices/curses_cons.c @@ -21,7 +21,7 @@ /* Interface between virtual video card and console */ #include -#include +#include #include #include #include @@ -42,6 +42,7 @@ struct cons_state { v3_console_t cons; int rows; int cols; + uint8_t * framebuf; struct vm_device * frontend_dev; }; @@ -62,7 +63,7 @@ static int cursor_update(uint_t x, uint_t y, void *private_data) struct cons_state *state = (struct cons_state *) dev->private_data; uint_t offset; - PrintDebug("cursor_update(%d, %d, %p)\n", x, y, private_data); + PrintDebug(VM_NONE, VCORE_NONE, "cursor_update(%d, %d, %p)\n", x, y, private_data); /* avoid out-of-range coordinates */ if (x < 0) x = 0; @@ -73,13 +74,13 @@ static int cursor_update(uint_t x, uint_t y, void *private_data) /* adjust cursor */ if (v3_console_set_cursor(state->cons, x, y) < 0) { - PrintError("set cursor (0x%p, %d, %d) failed\n", state->cons, x, y); + PrintError(VM_NONE, VCORE_NONE, "set cursor (0x%p, %d, %d) failed\n", state->cons, x, y); return -1; } /* done with console update */ if (v3_console_update(state->cons) < 0) { - PrintError("console update (0x%p) failed\n", state->cons); + PrintError(VM_NONE, VCORE_NONE, "console update (0x%p) failed\n", state->cons); return -1; } @@ -90,27 +91,31 @@ static int screen_update(uint_t x, uint_t y, uint_t length, void * private_data) struct vm_device * dev = (struct vm_device *)private_data; struct cons_state * state = (struct cons_state *)dev->private_data; uint_t offset = (x + y * state->cols) * BYTES_PER_COL; - uint8_t fb_buf[length]; int i; uint_t cur_x = x; uint_t cur_y = y; - PrintDebug("screen_update(%d, %d, %d, %p)\n", x, y, length, private_data); + if (length > (state->rows * state->cols * BYTES_PER_COL)) { + PrintError(VM_NONE, VCORE_NONE, "Screen update larger than curses framebuffer\n"); + return 0; + } + + PrintDebug(VM_NONE, VCORE_NONE, "screen_update(%d, %d, %d, %p)\n", x, y, length, private_data); /* grab frame buffer */ - v3_cons_get_fb(state->frontend_dev, fb_buf, offset, length); + v3_cons_get_fb(state->frontend_dev, state->framebuf, offset, length); /* update the screen */ for (i = 0; i < length; i += 2) { uint_t col_index = i; uint8_t col[2]; - col[0] = fb_buf[col_index]; // Character - col[1] = fb_buf[col_index + 1]; // Attribute + col[0] = state->framebuf[col_index]; // Character + col[1] = state->framebuf[col_index + 1]; // Attribute /* update current character */ if (v3_console_set_char(state->cons, cur_x, cur_y, col[0], col[1]) < 0) { - PrintError("set cursor (0x%p, %d, %d, %d, %d) failed\n", + PrintError(VM_NONE, VCORE_NONE, "set cursor (0x%p, %d, %d, %d, %d) failed\n", state->cons, cur_x, cur_y, col[1], col[0]); return -1; } @@ -123,7 +128,7 @@ static int screen_update(uint_t x, uint_t y, uint_t length, void * private_data) /* done with console update */ if (v3_console_update(state->cons) < 0) { - PrintError("console update(0x%p) failed\n", state->cons); + PrintError(VM_NONE, VCORE_NONE, "console update(0x%p) failed\n", state->cons); return -1; } @@ -134,7 +139,7 @@ static int scroll(int rows, void * private_data) { struct vm_device *dev = (struct vm_device *)private_data; struct cons_state *state = (struct cons_state *)dev->private_data; - PrintDebug("scroll(%d, %p)\n", rows, private_data); + PrintDebug(VM_NONE, VCORE_NONE, "scroll(%d, %p)\n", rows, private_data); if (rows < 0) { /* simply update the screen */ @@ -144,13 +149,13 @@ static int scroll(int rows, void * private_data) { if (rows > 0) { /* scroll requested number of lines*/ if (v3_console_scroll(state->cons, rows) < 0) { - PrintError("console scroll (0x%p, %u) failed\n", state->cons, rows); + PrintError(VM_NONE, VCORE_NONE, "console scroll (0x%p, %u) failed\n", state->cons, rows); return -1; } /* done with console update */ if (v3_console_update(state->cons) < 0) { - PrintError("console update (0x%p) failed\n", state->cons); + PrintError(VM_NONE, VCORE_NONE, "console update (0x%p) failed\n", state->cons); return -1; } } @@ -162,17 +167,17 @@ static int set_text_resolution(int cols, int rows, void * private_data) { struct vm_device *dev = (struct vm_device *)private_data; struct cons_state *state = (struct cons_state *)dev->private_data; - PrintDebug("set_text_resolution(%d, %d, %p)\n", cols, rows, private_data); + PrintDebug(VM_NONE, VCORE_NONE, "set_text_resolution(%d, %d, %p)\n", cols, rows, private_data); /* store resolution for internal use */ - V3_ASSERT(cols >= 1); - V3_ASSERT(rows >= 1); + V3_ASSERT(VM_NONE, VCORE_NONE, cols >= 1); + V3_ASSERT(VM_NONE, VCORE_NONE, rows >= 1); state->cols = cols; state->rows = rows; /* set notification regarding resolution change */ if (v3_console_set_text_resolution(state->cons, cols, rows) < 0) { - PrintError("console set_text_resolution (0x%p, %u, %u) failed\n", state->cons, cols, rows); + PrintError(VM_NONE, VCORE_NONE, "console set_text_resolution (0x%p, %u, %u) failed\n", state->cons, cols, rows); return -1; } @@ -210,30 +215,57 @@ static struct v3_device_ops dev_ops = { static int cons_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { struct cons_state * state = NULL; - v3_cfg_tree_t * frontend_cfg = v3_cfg_subtree(cfg, "frontend"); - const char * frontend_tag = v3_cfg_val(frontend_cfg, "tag"); - struct vm_device * frontend = v3_find_dev(vm, frontend_tag); + v3_cfg_tree_t * frontend_cfg; + const char * frontend_tag; + struct vm_device * frontend; char * dev_id = v3_cfg_val(cfg, "ID"); /* read configuration */ - V3_ASSERT(frontend_cfg); - V3_ASSERT(frontend_tag); - V3_ASSERT(frontend); + frontend_cfg = v3_cfg_subtree(cfg, "frontend"); + if (!frontend_cfg) { + PrintError(vm, VCORE_NONE, "No frontend specification for curses console.\n"); + return -1; + } + frontend_tag = v3_cfg_val(frontend_cfg, "tag"); + if (!frontend_tag) { + PrintError(vm, VCORE_NONE, "No frontend device tag specified for curses console.\n"); + return -1; + } + + frontend = v3_find_dev(vm, frontend_tag); + if (!frontend) { + PrintError(vm, VCORE_NONE, "Could not find frontend device %s for curses console.\n", + frontend_tag); + return -1; + } /* allocate state */ state = (struct cons_state *)V3_Malloc(sizeof(struct cons_state)); - V3_ASSERT(state); + + if (!state) { + PrintError(vm, VCORE_NONE, "Cannot allocate curses state\n"); + V3_Free(state); + return -1; + } state->frontend_dev = frontend; state->cols = 80; state->rows = 25; + state->framebuf = V3_Malloc(state->cols * state->rows * BYTES_PER_COL); + + if (!state->framebuf) { + PrintError(vm, VCORE_NONE, "Cannot allocate frame buffer\n"); + V3_Free(state); + return -1; + } /* open tty for screen display */ state->cons = v3_console_open(vm, state->cols, state->rows); if (!state->cons) { - PrintError("Could not open console\n"); + PrintError(vm, VCORE_NONE, "Could not open console\n"); + V3_Free(state->framebuf); V3_Free(state); return -1; } @@ -242,7 +274,8 @@ static int cons_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, state); if (dev == NULL) { - PrintError("Could not attach device %s\n", dev_id); + PrintError(vm, VCORE_NONE, "Could not attach device %s\n", dev_id); + V3_Free(state->framebuf); V3_Free(state); return -1; }