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. By the default the
builtin "Bochs Screen" EDID is used.
This commit is contained in:
Volker Ruppert 2020-03-21 18:00:02 +00:00
parent 3626b75791
commit e23a930864
7 changed files with 96 additions and 10 deletions

View File

@ -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:

View File

@ -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):

View File

@ -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(&params[i][12]));
} else if (!strncmp(params[i], "realtime=", 9)) {
SIM->get_param_bool(BXPN_VGA_REALTIME)->set(atol(&params[i][9]));
} else if (!strncmp(params[i], "ddc=", 4)) {
const char *strval = &params[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(),

View File

@ -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,

View File

@ -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;

View File

@ -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
};

View File

@ -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"