diff --git a/bochs/.bochsrc b/bochs/.bochsrc index 11b8c9797..11db35ccd 100644 --- a/bochs/.bochsrc +++ b/bochs/.bochsrc @@ -426,10 +426,15 @@ vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest # to 0 and "clock: sync=none" may improve the responsiveness of the guest # GUI when the guest is otherwise idle. # +# DDC +# This parameter defines the behaviour of the DDC emulation that returns +# the monitor EDID data. The default value is 'builtin' (use valus for +# 'Bochs Screen'). Other choices are 'off' (feature disabled) and 'file' +# (read monitor EDID from file, name separated with a colon). # Examples: -# vga: extension=cirrus, update_freq=10 +# vga: extension=cirrus, update_freq=10, ddc=builtin #======================================================================= -#vga: extension=vbe, update_freq=5, realtime=1 +#vga: extension=vbe, update_freq=5, realtime=1, ddc=file:monitor.bin #======================================================================= # VOODOO: diff --git a/bochs/CHANGES b/bochs/CHANGES index 2aa208589..30a7bb14f 100644 --- a/bochs/CHANGES +++ b/bochs/CHANGES @@ -15,6 +15,8 @@ Changes after 2.6.11: per model are supported. Use the zero-based "card" parameter to specify device. - VGA: Removed lfb_enabled switch from Bochs VBE code. Now banked and LFB writes to VRAM are always valid. Fixes GRUB bootloader menu when using Bochs VBE. + - VGA DDC: Added "ddc" parameter to the "vga" option to make it possible + either to disable the DDC feature or to read the monitor EDID from file. ------------------------------------------------------------------------- Changes in 2.6.11 (January 5, 2020): diff --git a/bochs/config.cc b/bochs/config.cc index e7a092bca..7b3583341 100644 --- a/bochs/config.cc +++ b/bochs/config.cc @@ -995,6 +995,28 @@ void bx_init_options() vga_extension->set_initial_val("vbe"); display->set_options(display->SHOW_PARENT); + static const char *ddc_mode_list[] = { + "off", + "builtin", + "file", + NULL + }; + bx_param_enum_c *ddc_mode = new bx_param_enum_c(display, + "ddc_mode", "DDC emulatiion mode", + "Select DDC emulation mode", + ddc_mode_list, + BX_DDC_MODE_BUILTIN, + BX_DDC_MODE_OFF); + path = new bx_param_filename_c(display, + "ddc_file", + "DDC definition file", + "Set path to a DDC definition file", + "", BX_PATHNAME_LEN); + deplist = new bx_list_c(NULL); + deplist->add(path); + ddc_mode->set_dependent_list(deplist, 0); + ddc_mode->set_dependent_bitmap(BX_DDC_MODE_FILE, 1); + // keyboard & mouse subtree bx_list_c *kbd_mouse = new bx_list_c(root_param, "keyboard_mouse", "Keyboard & Mouse Options"); bx_list_c *keyboard = new bx_list_c(kbd_mouse, "keyboard", "Keyboard Options"); @@ -2745,6 +2767,14 @@ static int parse_line_formatted(const char *context, int num_params, char *param SIM->get_param_num(BXPN_VGA_UPDATE_FREQUENCY)->set(atol(¶ms[i][12])); } else if (!strncmp(params[i], "realtime=", 9)) { SIM->get_param_bool(BXPN_VGA_REALTIME)->set(atol(¶ms[i][9])); + } else if (!strncmp(params[i], "ddc=", 4)) { + const char *strval = ¶ms[i][4]; + if (strncmp(strval, "file:", 5)) { + SIM->get_param_enum(BXPN_DDC_MODE)->set_by_name(strval); + } else { + SIM->get_param_enum(BXPN_DDC_MODE)->set(BX_DDC_MODE_FILE); + SIM->get_param_string(BXPN_DDC_FILE)->set(strval+5); + } } else { PARSE_ERR(("%s: vga directive malformed.", context)); } @@ -3384,10 +3414,15 @@ int bx_write_configuration(const char *rc, int overwrite) } } fprintf(fp, "\n"); - fprintf(fp, "vga: extension=%s, update_freq=%u, realtime=%u\n", + fprintf(fp, "vga: extension=%s, update_freq=%u, realtime=%u, ddc=%s", SIM->get_param_string(BXPN_VGA_EXTENSION)->getptr(), SIM->get_param_num(BXPN_VGA_UPDATE_FREQUENCY)->get(), - SIM->get_param_bool(BXPN_VGA_REALTIME)->get()); + SIM->get_param_bool(BXPN_VGA_REALTIME)->get(), + SIM->get_param_enum(BXPN_DDC_MODE)->get_selected()); + if (SIM->get_param_enum(BXPN_DDC_MODE)->get() == BX_DDC_MODE_FILE) { + fprintf(fp, ":%s", SIM->get_param_string(BXPN_DDC_FILE)->getptr()); + } + fprintf(fp, "\n"); #if BX_SUPPORT_SMP fprintf(fp, "cpu: count=%u:%u:%u, ips=%u, quantum=%d, ", SIM->get_param_num(BXPN_CPU_NPROCESSORS)->get(), SIM->get_param_num(BXPN_CPU_NCORES)->get(), diff --git a/bochs/gui/siminterface.h b/bochs/gui/siminterface.h index d4f15e006..c9523b41b 100644 --- a/bochs/gui/siminterface.h +++ b/bochs/gui/siminterface.h @@ -2,7 +2,7 @@ // $Id$ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2001-2018 The Bochs Project +// Copyright (C) 2001-2020 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -485,6 +485,12 @@ enum { BX_RUN_START }; +enum { + BX_DDC_MODE_OFF, + BX_DDC_MODE_BUILTIN, + BX_DDC_MODE_FILE +}; + enum { BX_MOUSE_TYPE_NONE, BX_MOUSE_TYPE_PS2, diff --git a/bochs/iodev/display/ddc.cc b/bochs/iodev/display/ddc.cc index f1739115e..f4bb8e3e3 100644 --- a/bochs/iodev/display/ddc.cc +++ b/bochs/iodev/display/ddc.cc @@ -2,7 +2,7 @@ // $Id$ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2018 The Bochs Project +// Copyright (C) 2018-2020 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -18,8 +18,7 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// DDC stub (when ready, this code should return the VESA EDID for the -// Bochs plug&play monitor) +// DDC support (returns the VESA EDID for the Bochs plug&play monitor) // Define BX_PLUGGABLE in files that can be compiled into plugins. For // platforms that require a special tag on exported symbols, BX_PLUGGABLE @@ -28,6 +27,7 @@ #include "bochs.h" #include "ddc.h" +#include "param_names.h" #define LOG_THIS @@ -153,6 +153,10 @@ const Bit8u vesa_EDID[128] = { bx_ddc_c::bx_ddc_c(void) { + int fd, ret; + struct stat stat_buf; + const char *path; + put("DDC"); s.DCKhost = 1; s.DDAhost = 1; @@ -161,6 +165,33 @@ bx_ddc_c::bx_ddc_c(void) s.ddc_ack = 1; s.ddc_rw = 1; s.edid_index = 0; + s.ddc_mode = SIM->get_param_enum(BXPN_DDC_MODE)->get(); + if (s.ddc_mode == BX_DDC_MODE_BUILTIN) { + memcpy(s.edid_data, vesa_EDID, 128); + } else if (s.ddc_mode == BX_DDC_MODE_FILE) { + path = SIM->get_param_string(BXPN_DDC_FILE)->getptr(); + fd = open(path, O_RDONLY +#ifdef O_BINARY + | O_BINARY +#endif + ); + if (fd < 0) { + BX_PANIC(("failed to open monitor EDID file '%s'", path)); + } + ret = fstat(fd, &stat_buf); + if (ret) { + BX_PANIC(("could not fstat() monitor EDID file.")); + } + if (stat_buf.st_size != 128) { + BX_PANIC(("monitor EDID file size must be 128 bytes")); + } + ret = ::read(fd, (bx_ptr_t) s.edid_data, (unsigned)stat_buf.st_size); + if (ret != stat_buf.st_size) { + BX_PANIC(("error reading monitor EDID file.")); + } + close(fd); + BX_INFO(("Monitor EDID read from image file '%s'.", path)); + } } bx_ddc_c::~bx_ddc_c(void) @@ -179,6 +210,9 @@ void bx_ddc_c::write(bx_bool dck, bx_bool dda) bx_bool dck_change = 0; bx_bool dda_change = 0; + if (s.ddc_mode == BX_DDC_MODE_OFF) + return; + if ((dck != s.DCKhost) || (dda != s.DDAhost)) { dck_change = (dck != s.DCKhost); dda_change = (dda != s.DDAhost); @@ -283,7 +317,7 @@ void bx_ddc_c::write(bx_bool dck, bx_bool dda) Bit8u bx_ddc_c::get_edid_byte() { - Bit8u value = vesa_EDID[s.edid_index++]; + Bit8u value = s.edid_data[s.edid_index++]; BX_DEBUG(("Sending EDID byte %d (value = 0x%02x)", s.edid_index - 1, value)); s.edid_index &= 0x7f; return value; diff --git a/bochs/iodev/display/ddc.h b/bochs/iodev/display/ddc.h index da0357669..7312a9f38 100644 --- a/bochs/iodev/display/ddc.h +++ b/bochs/iodev/display/ddc.h @@ -2,7 +2,7 @@ // $Id$ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2018 The Bochs Project +// Copyright (C) 2018-2020 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -35,6 +35,7 @@ private: Bit8u get_edid_byte(void); struct { + Bit8u ddc_mode; bx_bool DCKhost; bx_bool DDAhost; bx_bool DDAmon; @@ -44,6 +45,7 @@ private: bx_bool ddc_rw; Bit8u ddc_byte; Bit8u edid_index; + Bit8u edid_data[128]; } s; // state information }; diff --git a/bochs/param_names.h b/bochs/param_names.h index 82f7b7e3b..1a8d4e49a 100644 --- a/bochs/param_names.h +++ b/bochs/param_names.h @@ -107,6 +107,8 @@ #define BXPN_VGA_EXTENSION "display.vga_extension" #define BXPN_VGA_UPDATE_FREQUENCY "display.vga_update_frequency" #define BXPN_VGA_REALTIME "display.vga_realtime" +#define BXPN_DDC_MODE "display.ddc_mode" +#define BXPN_DDC_FILE "display.ddc_file" #define BXPN_VOODOO "display.voodoo" #define BXPN_KEYBOARD "keyboard_mouse.keyboard" #define BXPN_KBD_TYPE "keyboard_mouse.keyboard.type"