7ad9aa5292
- GTK UHCI dialog: Added support for saving changes to controller. - Improved GTK xHCI debug dialog (TODO: tree view, save to controller). - win32 USB debugger: removed no longer needed include statement.
778 lines
32 KiB
C++
778 lines
32 KiB
C++
/////////////////////////////////////////////////////////////////////////
|
|
// $Id$
|
|
/////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (C) 2023 Benjamin David Lunt
|
|
// Copyright (C) 2003-2024 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
|
|
// License as published by the Free Software Foundation; either
|
|
// version 2 of the License, or (at your option) any later version.
|
|
//
|
|
// This library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
// Lesser General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
// License along with this library; if not, write to the Free Software
|
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
#include "bochs.h"
|
|
#include "siminterface.h"
|
|
#include "param_names.h"
|
|
|
|
#if BX_USB_DEBUGGER
|
|
|
|
#include "usb_debug.h"
|
|
// hack for xHCI
|
|
#include "iodev.h"
|
|
#include "iodev/usb/usb_common.h"
|
|
#include "iodev/usb/usb_xhci.h"
|
|
|
|
#include <gtk/gtk.h>
|
|
#include <glib.h>
|
|
|
|
typedef struct {
|
|
const char *name;
|
|
GtkWidget *entry;
|
|
Bit8u fmt_size;
|
|
const struct S_ATTRIBUTES *attr;
|
|
} usb_reg_t;
|
|
|
|
const char *chkTxt[6] = {"Reset", "Enable", "Event", "Doorbell", "Start of Frame", "Non-Exist"};
|
|
const char *chkBXPN[6] = {BXPN_USB_DEBUG_RESET, BXPN_USB_DEBUG_ENABLE, BXPN_USB_DEBUG_EVENT,
|
|
BXPN_USB_DEBUG_DOORBELL, BXPN_USB_DEBUG_START_FRAME, BXPN_USB_DEBUG_NON_EXIST};
|
|
|
|
GtkWidget *main_dialog;
|
|
GtkWidget *uhci_entry[UHCI_REG_COUNT];
|
|
GtkWidget *DFframe, *DFvbox, *checkbox[6];
|
|
GtkWidget *apply_button;
|
|
|
|
// multithreading using pure posix threads -- not glib threads
|
|
static void * EventLp(void *data)
|
|
{
|
|
gtk_main();
|
|
return NULL;
|
|
}
|
|
|
|
static void MakeGTKthreads()
|
|
{
|
|
pthread_t hThread;
|
|
pthread_create(&hThread, NULL, EventLp, NULL);
|
|
}
|
|
|
|
GtkWidget* usbdlg_create_label(GtkWidget *box, const char *text, bool expand = true)
|
|
{
|
|
GtkWidget *label = gtk_label_new(text);
|
|
gtk_box_pack_start(GTK_BOX(box), label, expand, expand, 2);
|
|
return label;
|
|
}
|
|
|
|
GtkWidget* usbdlg_create_entry_with_label(GtkWidget **box, const char *text,
|
|
bool expand = true)
|
|
{
|
|
gtk_box_pack_start(GTK_BOX(box[0]), gtk_label_new(text), expand, expand, 2);
|
|
GtkWidget *entry = gtk_entry_new();
|
|
gtk_box_pack_start(GTK_BOX(box[1]), entry, expand, expand, 2);
|
|
return entry;
|
|
}
|
|
|
|
GtkWidget* usbdlg_create_ro_entry(GtkWidget *box, bool expand = true)
|
|
{
|
|
GtkWidget *entry = gtk_entry_new();
|
|
gtk_widget_set_sensitive(entry, 0);
|
|
gtk_box_pack_start(GTK_BOX(box), entry, expand, expand, 2);
|
|
return entry;
|
|
}
|
|
|
|
GtkWidget* usbdlg_create_ro_entry_with_label(GtkWidget **box, const char *text,
|
|
bool expand = true)
|
|
{
|
|
gtk_box_pack_start(GTK_BOX(box[0]), gtk_label_new(text), expand, expand, 2);
|
|
GtkWidget *entry = gtk_entry_new();
|
|
gtk_widget_set_sensitive(entry, 0);
|
|
gtk_box_pack_start(GTK_BOX(box[1]), entry, expand, expand, 2);
|
|
return entry;
|
|
}
|
|
|
|
void usbdlg_create_debug_flags(GtkWidget *vbox)
|
|
{
|
|
DFframe = gtk_frame_new("Debug Flags");
|
|
gtk_box_pack_start(GTK_BOX(vbox), DFframe, FALSE, FALSE, 2);
|
|
DFvbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
|
gtk_container_add(GTK_CONTAINER(DFframe), DFvbox);
|
|
for (int i = 0; i < 6; i++) {
|
|
checkbox[i] = gtk_check_button_new_with_label(chkTxt[i]);
|
|
if (SIM->get_param_num(chkBXPN[i])->get() > 0) {
|
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbox[i]), TRUE);
|
|
}
|
|
gtk_box_pack_start(GTK_BOX(DFvbox), checkbox[i], FALSE, FALSE, 2);
|
|
}
|
|
}
|
|
|
|
void usbdlg_set_debug_flags()
|
|
{
|
|
for (int i = 0; i < 6; i++) {
|
|
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbox[i]))) {
|
|
SIM->get_param_num(chkBXPN[i])->set(1);
|
|
} else {
|
|
SIM->get_param_num(chkBXPN[i])->set(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void usb_regview_dialog(GtkWidget *widget, gpointer data)
|
|
{
|
|
int i, ret;
|
|
char buffer[32], format[10];
|
|
Bit32u oldval, value;
|
|
|
|
usb_reg_t *usb_reg_def = (usb_reg_t*)data;
|
|
GtkWidget *dialog =
|
|
gtk_dialog_new_with_buttons(usb_reg_def->name, GTK_WINDOW(main_dialog), GTK_DIALOG_MODAL,
|
|
g_dgettext("gtk30", "_OK"), GTK_RESPONSE_OK,
|
|
g_dgettext("gtk30", "_Cancel"), GTK_RESPONSE_CANCEL,
|
|
NULL);
|
|
gtk_window_set_default_size(GTK_WINDOW(dialog), 250, 250);
|
|
GtkWidget *listbox = gtk_list_box_new();
|
|
gtk_list_box_set_selection_mode(GTK_LIST_BOX(listbox), GTK_SELECTION_MULTIPLE);
|
|
gtk_list_box_set_activate_on_single_click(GTK_LIST_BOX(listbox), 1);
|
|
i = 0;
|
|
while (usb_reg_def->attr[i].index > -1) {
|
|
gtk_list_box_insert(GTK_LIST_BOX(listbox), gtk_label_new(usb_reg_def->attr[i].str), -1);
|
|
i++;
|
|
}
|
|
gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), listbox, TRUE, TRUE, 2);
|
|
// Show dialog
|
|
gtk_widget_show_all(dialog);
|
|
oldval = strtoul(gtk_entry_get_text(GTK_ENTRY(usb_reg_def->entry)), NULL, 16);
|
|
i = 0;
|
|
while (usb_reg_def->attr[i].index > -1) {
|
|
if ((oldval & usb_reg_def->attr[i].mask) != 0) {
|
|
gtk_list_box_select_row(GTK_LIST_BOX(listbox),
|
|
gtk_list_box_get_row_at_index(GTK_LIST_BOX(listbox), i));
|
|
} else {
|
|
gtk_list_box_unselect_row(GTK_LIST_BOX(listbox),
|
|
gtk_list_box_get_row_at_index(GTK_LIST_BOX(listbox), i));
|
|
}
|
|
i++;
|
|
}
|
|
ret = gtk_dialog_run(GTK_DIALOG(dialog));
|
|
if (ret == GTK_RESPONSE_OK) {
|
|
value = 0;
|
|
i = 0;
|
|
while (usb_reg_def->attr[i].index > -1) {
|
|
if (gtk_list_box_row_is_selected(gtk_list_box_get_row_at_index(GTK_LIST_BOX(listbox), i))) {
|
|
value |= usb_reg_def->attr[i].mask;
|
|
}
|
|
i++;
|
|
}
|
|
if (value != oldval) {
|
|
sprintf(format, "0x%%0%iX", usb_reg_def->fmt_size);
|
|
sprintf(buffer, format, value);
|
|
gtk_entry_set_text(GTK_ENTRY(usb_reg_def->entry), buffer);
|
|
}
|
|
}
|
|
gtk_widget_destroy(dialog);
|
|
}
|
|
|
|
// Save UHCI state to controller
|
|
|
|
int hc_uhci_save()
|
|
{
|
|
char buffer[COMMON_STR_SIZE];
|
|
|
|
if (u_changed[UHCI_REG_COMMAND]) {
|
|
strcpy(buffer, gtk_entry_get_text(GTK_ENTRY(uhci_entry[UHCI_REG_COMMAND])));
|
|
usb_io_write(pci_bar_address + 0, strtol(buffer, NULL, 0), 2);
|
|
}
|
|
if (u_changed[UHCI_REG_STATUS]) {
|
|
strcpy(buffer, gtk_entry_get_text(GTK_ENTRY(uhci_entry[UHCI_REG_STATUS])));
|
|
usb_io_write(pci_bar_address + 2, strtol(buffer, NULL, 0), 2);
|
|
}
|
|
if (u_changed[UHCI_REG_INTERRUPT]) {
|
|
strcpy(buffer, gtk_entry_get_text(GTK_ENTRY(uhci_entry[UHCI_REG_INTERRUPT])));
|
|
usb_io_write(pci_bar_address + 4, strtol(buffer, NULL, 0), 2);
|
|
}
|
|
if (u_changed[UHCI_REG_FRAME_NUM]) {
|
|
strcpy(buffer, gtk_entry_get_text(GTK_ENTRY(uhci_entry[UHCI_REG_FRAME_NUM])));
|
|
usb_io_write(pci_bar_address + 6, strtol(buffer, NULL, 0), 2);
|
|
}
|
|
if (u_changed[UHCI_REG_FRAME_ADDR]) {
|
|
strcpy(buffer, gtk_entry_get_text(GTK_ENTRY(uhci_entry[UHCI_REG_FRAME_ADDR])));
|
|
usb_io_write(pci_bar_address + 8, strtol(buffer, NULL, 0), 4);
|
|
}
|
|
if (u_changed[UHCI_REG_SOF]) {
|
|
strcpy(buffer, gtk_entry_get_text(GTK_ENTRY(uhci_entry[UHCI_REG_SOF])));
|
|
usb_io_write(pci_bar_address + 12, strtol(buffer, NULL, 0), 1);
|
|
}
|
|
if (u_changed[UHCI_REG_PORT0]) {
|
|
strcpy(buffer, gtk_entry_get_text(GTK_ENTRY(uhci_entry[UHCI_REG_PORT0])));
|
|
usb_io_write(pci_bar_address + 16, strtol(buffer, NULL, 0), 2);
|
|
}
|
|
if (u_changed[UHCI_REG_PORT1]) {
|
|
strcpy(buffer, gtk_entry_get_text(GTK_ENTRY(uhci_entry[UHCI_REG_PORT1])));
|
|
usb_io_write(pci_bar_address + 18, strtol(buffer, NULL, 0), 2);
|
|
}
|
|
|
|
memset(u_changed, 0, sizeof(u_changed));
|
|
gtk_widget_set_sensitive(apply_button, 0);
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Apply button support
|
|
|
|
static void on_entry_changed(GtkWidget *widget, gpointer data)
|
|
{
|
|
*((bool*)data) = 1;
|
|
gtk_widget_set_sensitive(apply_button, 1);
|
|
}
|
|
|
|
static void apply_changes(GtkWidget *widget, gpointer data)
|
|
{
|
|
if (usb_debug_type == USB_DEBUG_UHCI) {
|
|
hc_uhci_save();
|
|
} else {
|
|
GtkWidget* error = gtk_message_dialog_new(
|
|
GTK_WINDOW(main_dialog), GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
|
|
"Saving changes to controller not implemented yet");
|
|
gtk_window_set_title(GTK_WINDOW(error), "WARNING");
|
|
gtk_dialog_run(GTK_DIALOG(error));
|
|
gtk_widget_destroy(error);
|
|
}
|
|
}
|
|
|
|
void usbdlg_create_apply_button(GtkWidget *vbox)
|
|
{
|
|
GtkWidget *apply_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
|
gtk_box_pack_start(GTK_BOX(vbox), apply_hbox, FALSE, FALSE, 2);
|
|
apply_button = gtk_button_new_with_label(g_dgettext("gtk30", "_Apply"));
|
|
gtk_widget_set_sensitive(apply_button, 0);
|
|
g_signal_connect(apply_button, "clicked", G_CALLBACK(apply_changes), NULL);
|
|
gtk_box_pack_start(GTK_BOX(apply_hbox), apply_button, FALSE, FALSE, 2);
|
|
}
|
|
|
|
// UHCI main dialog
|
|
|
|
int uhci_debug_dialog(int type, int param1)
|
|
{
|
|
bx_list_c *UHCI_state = NULL;
|
|
int i, ret;
|
|
Bit32u frame_addr, frame_num;
|
|
char buffer[COMMON_STR_SIZE];
|
|
GtkWidget *mainVbox, *BAhbox, *hbox[2], *vbox[3], *ro_entry[4];
|
|
GtkWidget *ORframe, *ORhbox, *ORvbox[3];
|
|
GtkWidget *PRframe, *PRhbox, *PRvbox[3];
|
|
GtkWidget *TVvbox, *FNhbox;
|
|
GtkWidget *button[8], *FNlabel, *treeview;
|
|
usb_reg_t uhci_reg_def[5] = {
|
|
{"Command Register", NULL, 4, attribs_u_command},
|
|
{"Status Register", NULL, 4, attribs_u_status},
|
|
{"Interrupt Enable Register", NULL, 4, attribs_u_interrupt},
|
|
{"Port 0 Register", NULL, 4, attribs_u_ports},
|
|
{"Port 1 Register", NULL, 4, attribs_u_ports}
|
|
};
|
|
|
|
UHCI_state = (bx_list_c*)SIM->get_param("usb_uhci", SIM->get_bochs_root());
|
|
if (UHCI_state == NULL)
|
|
return -1;
|
|
|
|
main_dialog = gtk_dialog_new();
|
|
switch (type) {
|
|
case USB_DEBUG_FRAME:
|
|
gtk_window_set_title(GTK_WINDOW(main_dialog), "UHCI Debug Dialog: Break Type: Start of Frame");
|
|
break;
|
|
case USB_DEBUG_COMMAND:
|
|
gtk_window_set_title(GTK_WINDOW(main_dialog), "UHCI Debug Dialog: Break Type: Doorbell");
|
|
break;
|
|
case USB_DEBUG_NONEXIST:
|
|
gtk_window_set_title(GTK_WINDOW(main_dialog), "UHCI Debug Dialog: Break Type: Non-Existant Port Write");
|
|
break;
|
|
case USB_DEBUG_RESET:
|
|
sprintf(buffer, "UHCI Debug Dialog: Break Type: Port %d Reset", param1);
|
|
gtk_window_set_title(GTK_WINDOW(main_dialog), buffer);
|
|
break;
|
|
case USB_DEBUG_ENABLE:
|
|
sprintf(buffer, "UHCI Debug Dialog: Break Type: Port %d Enable", param1);
|
|
gtk_window_set_title(GTK_WINDOW(main_dialog), buffer);
|
|
break;
|
|
default:
|
|
gtk_window_set_title(GTK_WINDOW(main_dialog), "UHCI Debug Dialog");
|
|
}
|
|
gtk_window_set_default_size(GTK_WINDOW(main_dialog), 600, 500);
|
|
button[0] = gtk_dialog_add_button(GTK_DIALOG(main_dialog), "Continue", GTK_RESPONSE_OK);
|
|
button[1] = gtk_dialog_add_button(GTK_DIALOG(main_dialog), "Quit", GTK_RESPONSE_CANCEL);
|
|
gtk_dialog_set_default_response(GTK_DIALOG(main_dialog), GTK_RESPONSE_OK);
|
|
gtk_window_set_focus(GTK_WINDOW(main_dialog), button[0]);
|
|
mainVbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
|
gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(main_dialog))), mainVbox, TRUE, TRUE, 2);
|
|
|
|
BAhbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
|
gtk_box_pack_start(GTK_BOX(mainVbox), BAhbox, FALSE, FALSE, 2);
|
|
usbdlg_create_label(BAhbox, "UHCI at Base IO address", false);
|
|
ro_entry[0] = usbdlg_create_ro_entry(BAhbox, false);
|
|
|
|
hbox[0] = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
|
gtk_box_pack_start(GTK_BOX(mainVbox), hbox[0], TRUE, TRUE, 2);
|
|
hbox[1] = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
|
gtk_box_pack_start(GTK_BOX(mainVbox), hbox[1], TRUE, TRUE, 2);
|
|
for (i = 0; i < 3; i++) {
|
|
vbox[i] = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
|
gtk_box_pack_start(GTK_BOX(hbox[0]), vbox[i], TRUE, TRUE, 2);
|
|
}
|
|
|
|
ORframe = gtk_frame_new("Operational Registers");
|
|
gtk_box_pack_start(GTK_BOX(vbox[0]), ORframe, FALSE, FALSE, 2);
|
|
ORhbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
|
gtk_container_add(GTK_CONTAINER(ORframe), ORhbox);
|
|
for (i = 0; i < 3; i++) {
|
|
ORvbox[i] = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
|
gtk_box_pack_start(GTK_BOX(ORhbox), ORvbox[i], FALSE, FALSE, 2);
|
|
}
|
|
uhci_entry[UHCI_REG_COMMAND] = usbdlg_create_entry_with_label(ORvbox, "Command");
|
|
button[2] = gtk_button_new_with_label("<>");
|
|
uhci_reg_def[0].entry = uhci_entry[UHCI_REG_COMMAND];
|
|
g_signal_connect(button[2], "clicked", G_CALLBACK(usb_regview_dialog), &uhci_reg_def[0]);
|
|
gtk_box_pack_start(GTK_BOX(ORvbox[2]), button[2], FALSE, FALSE, 2);
|
|
uhci_entry[UHCI_REG_STATUS] = usbdlg_create_entry_with_label(ORvbox, "Status");
|
|
button[3] = gtk_button_new_with_label("<>");
|
|
uhci_reg_def[1].entry = uhci_entry[UHCI_REG_STATUS];
|
|
g_signal_connect(button[3], "clicked", G_CALLBACK(usb_regview_dialog), &uhci_reg_def[1]);
|
|
gtk_box_pack_start(GTK_BOX(ORvbox[2]), button[3], FALSE, FALSE, 2);
|
|
uhci_entry[UHCI_REG_INTERRUPT] = usbdlg_create_entry_with_label(ORvbox, "Interrupt Enable");
|
|
button[4] = gtk_button_new_with_label("<>");
|
|
uhci_reg_def[2].entry = uhci_entry[UHCI_REG_INTERRUPT];
|
|
g_signal_connect(button[4], "clicked", G_CALLBACK(usb_regview_dialog), &uhci_reg_def[2]);
|
|
gtk_box_pack_start(GTK_BOX(ORvbox[2]), button[4], FALSE, FALSE, 2);
|
|
uhci_entry[UHCI_REG_FRAME_NUM] = usbdlg_create_entry_with_label(ORvbox, "Frame Number");
|
|
uhci_entry[UHCI_REG_FRAME_ADDR] = usbdlg_create_entry_with_label(ORvbox, "Frame Address");
|
|
uhci_entry[UHCI_REG_SOF] = usbdlg_create_entry_with_label(ORvbox, "Start of Frame");
|
|
|
|
PRframe = gtk_frame_new("Port Registers");
|
|
gtk_box_pack_start(GTK_BOX(hbox[1]), PRframe, FALSE, FALSE, 2);
|
|
PRhbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
|
gtk_container_add(GTK_CONTAINER(PRframe), PRhbox);
|
|
for (i = 0; i < 3; i++) {
|
|
PRvbox[i] = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
|
gtk_box_pack_start(GTK_BOX(PRhbox), PRvbox[i], FALSE, FALSE, 2);
|
|
}
|
|
for (i = 0; i < 2; i++) {
|
|
sprintf(buffer, "Port %d", i);
|
|
uhci_entry[UHCI_REG_PORT0 + i] = usbdlg_create_entry_with_label(PRvbox, buffer);
|
|
ro_entry[i + 1] = usbdlg_create_ro_entry_with_label(PRvbox, "Emulation Type");
|
|
button[i + 5] = gtk_button_new_with_label("<>");
|
|
uhci_reg_def[i + 3].entry = uhci_entry[UHCI_REG_PORT0 + i];
|
|
g_signal_connect(button[i + 5], "clicked", G_CALLBACK(usb_regview_dialog), &uhci_reg_def[i + 3]);
|
|
gtk_box_pack_start(GTK_BOX(PRvbox[2]), button[i + 5], FALSE, FALSE, 2);
|
|
gtk_box_pack_start(GTK_BOX(PRvbox[2]), gtk_label_new(" "), FALSE, FALSE, 8); // spacer
|
|
}
|
|
TVvbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
|
gtk_box_pack_start(GTK_BOX(hbox[1]), TVvbox, TRUE, TRUE, 2);
|
|
FNhbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
|
gtk_box_pack_start(GTK_BOX(TVvbox), FNhbox, FALSE, FALSE, 2);
|
|
FNlabel = usbdlg_create_label(FNhbox, "Frame at Address", false);
|
|
ro_entry[3] = usbdlg_create_ro_entry(FNhbox, false);
|
|
button[7] = gtk_button_new_with_label("View Item");
|
|
gtk_widget_set_sensitive(button[7], 0);
|
|
gtk_box_pack_start(GTK_BOX(FNhbox), button[7], FALSE, FALSE, 2);
|
|
treeview = gtk_tree_view_new();
|
|
gtk_box_pack_start(GTK_BOX(TVvbox), treeview, TRUE, TRUE, 2);
|
|
|
|
usbdlg_create_apply_button(mainVbox);
|
|
usbdlg_create_debug_flags(vbox[2]);
|
|
// Set values
|
|
pci_bar_address = get_pci_bar_addr((bx_shadow_data_c*)SIM->get_param("hub.pci_conf", UHCI_state), 4);
|
|
sprintf(buffer, "0x%04X", pci_bar_address);
|
|
gtk_entry_set_text(GTK_ENTRY(ro_entry[0]), buffer);
|
|
sprintf(buffer, "0x%04X", usb_io_read(pci_bar_address + 0, 2));
|
|
gtk_entry_set_text(GTK_ENTRY(uhci_entry[UHCI_REG_COMMAND]), buffer);
|
|
g_signal_connect(GTK_EDITABLE(uhci_entry[UHCI_REG_COMMAND]), "changed",
|
|
G_CALLBACK(on_entry_changed), &u_changed[UHCI_REG_COMMAND]);
|
|
sprintf(buffer, "0x%04X", usb_io_read(pci_bar_address + 2, 2));
|
|
gtk_entry_set_text(GTK_ENTRY(uhci_entry[UHCI_REG_STATUS]), buffer);
|
|
g_signal_connect(GTK_EDITABLE(uhci_entry[UHCI_REG_STATUS]), "changed",
|
|
G_CALLBACK(on_entry_changed), &u_changed[UHCI_REG_STATUS]);
|
|
sprintf(buffer, "0x%04X", usb_io_read(pci_bar_address + 4, 2));
|
|
gtk_entry_set_text(GTK_ENTRY(uhci_entry[UHCI_REG_INTERRUPT]), buffer);
|
|
g_signal_connect(GTK_EDITABLE(uhci_entry[UHCI_REG_INTERRUPT]), "changed",
|
|
G_CALLBACK(on_entry_changed), &u_changed[UHCI_REG_INTERRUPT]);
|
|
frame_num = usb_io_read(pci_bar_address + 6, 2);
|
|
sprintf(buffer, "0x%04X", frame_num);
|
|
gtk_entry_set_text(GTK_ENTRY(uhci_entry[UHCI_REG_FRAME_NUM]), buffer);
|
|
g_signal_connect(GTK_EDITABLE(uhci_entry[UHCI_REG_FRAME_NUM]), "changed",
|
|
G_CALLBACK(on_entry_changed), &u_changed[UHCI_REG_FRAME_NUM]);
|
|
frame_addr = usb_io_read(pci_bar_address + 8, 4);
|
|
sprintf(buffer, "0x%08X", frame_addr);
|
|
gtk_entry_set_text(GTK_ENTRY(uhci_entry[UHCI_REG_FRAME_ADDR]), buffer);
|
|
g_signal_connect(GTK_EDITABLE(uhci_entry[UHCI_REG_FRAME_ADDR]), "changed",
|
|
G_CALLBACK(on_entry_changed), &u_changed[UHCI_REG_FRAME_ADDR]);
|
|
sprintf(buffer, "0x%02X", usb_io_read(pci_bar_address + 12, 1));
|
|
gtk_entry_set_text(GTK_ENTRY(uhci_entry[UHCI_REG_SOF]), buffer);
|
|
g_signal_connect(GTK_EDITABLE(uhci_entry[UHCI_REG_SOF]), "changed",
|
|
G_CALLBACK(on_entry_changed), &u_changed[UHCI_REG_SOF]);
|
|
sprintf(buffer, "0x%04X", usb_io_read(pci_bar_address + 16, 2));
|
|
gtk_entry_set_text(GTK_ENTRY(uhci_entry[UHCI_REG_PORT0]), buffer);
|
|
g_signal_connect(GTK_EDITABLE(uhci_entry[UHCI_REG_PORT0]), "changed",
|
|
G_CALLBACK(on_entry_changed), &u_changed[UHCI_REG_PORT0]);
|
|
SIM->get_param_enum("port1.device", host_param)->dump_param(buffer, COMMON_STR_SIZE, 1);
|
|
gtk_entry_set_text(GTK_ENTRY(ro_entry[1]), buffer);
|
|
sprintf(buffer, "0x%04X", usb_io_read(pci_bar_address + 18, 2));
|
|
gtk_entry_set_text(GTK_ENTRY(uhci_entry[UHCI_REG_PORT1]), buffer);
|
|
g_signal_connect(GTK_EDITABLE(uhci_entry[UHCI_REG_PORT1]), "changed",
|
|
G_CALLBACK(on_entry_changed), &u_changed[UHCI_REG_PORT1]);
|
|
SIM->get_param_enum("port2.device", host_param)->dump_param(buffer, COMMON_STR_SIZE, 1);
|
|
gtk_entry_set_text(GTK_ENTRY(ro_entry[2]), buffer);
|
|
|
|
frame_addr += (frame_num * sizeof(Bit32u));
|
|
sprintf(buffer, "0x%08X", frame_addr);
|
|
gtk_entry_set_text(GTK_ENTRY(ro_entry[3]), buffer);
|
|
|
|
bool valid = 0;
|
|
switch (type) {
|
|
// The DoTransfer() function was called
|
|
case USB_DEBUG_COMMAND:
|
|
// The start of a frame timer was triggered
|
|
case USB_DEBUG_FRAME:
|
|
gtk_label_set_text(GTK_LABEL(FNlabel), "SOF Frame Address");
|
|
if (frame_addr != 0x00000000) {
|
|
gtk_widget_set_sensitive(button[7], 1);
|
|
valid = 1;
|
|
}
|
|
break;
|
|
|
|
// an event triggered. We ignore these in the uhci
|
|
//case USB_DEBUG_EVENT:
|
|
// break;
|
|
|
|
// first byte (word, dword, qword) of first non-existant port was written to
|
|
case USB_DEBUG_NONEXIST:
|
|
// port reset (non-root reset)
|
|
case USB_DEBUG_RESET:
|
|
// enable changed
|
|
case USB_DEBUG_ENABLE:
|
|
gtk_label_set_text(GTK_LABEL(FNlabel), "None");
|
|
gtk_entry_set_text(GTK_ENTRY(ro_entry[3]), "None");
|
|
break;
|
|
}
|
|
|
|
if (!valid) {
|
|
gtk_widget_set_sensitive(treeview, 0);
|
|
usbdlg_create_label(TVvbox, "This trigger does not populate the tree view", false);
|
|
} else {
|
|
usbdlg_create_label(TVvbox, "Tree view populated", false);
|
|
}
|
|
// Show dialog
|
|
gtk_widget_show_all(main_dialog);
|
|
ret = gtk_dialog_run(GTK_DIALOG(main_dialog));
|
|
if (ret == GTK_RESPONSE_OK) {
|
|
usbdlg_set_debug_flags();
|
|
}
|
|
gtk_widget_destroy(main_dialog);
|
|
return ret;
|
|
}
|
|
|
|
// xHCI main dialog
|
|
|
|
int xhci_debug_dialog(int type, int param1)
|
|
{
|
|
bx_list_c *xHCI_state = NULL;
|
|
int i, n_ports, ret;
|
|
Bit32u dword, offset;
|
|
Bit64u RingPtr = 0;
|
|
char buffer[COMMON_STR_SIZE], tmpbuf[32];
|
|
GtkWidget *mainVbox, *BAhbox, *hbox[2], *vbox[4], *entry[38];
|
|
GtkWidget *CRframe, *CRhbox, *CRvbox[2];
|
|
GtkWidget *ORframe, *ORhbox, *ORvbox[2];
|
|
GtkWidget *RTframe, *RThbox, *RTvbox[2];
|
|
GtkWidget *PRframe, *PRhbox, *PRvbox[3];
|
|
GtkWidget *TVvbox, *FNhbox;
|
|
GtkWidget *button[13], *FNlabel, *treeview;
|
|
usb_reg_t xhci_reg_def[10] = {
|
|
{"Port 0 Register", NULL, 8, attribs_x_ports},
|
|
{"Port 1 Register", NULL, 8, attribs_x_ports},
|
|
{"Port 2 Register", NULL, 8, attribs_x_ports},
|
|
{"Port 3 Register", NULL, 8, attribs_x_ports},
|
|
{"Port 4 Register", NULL, 8, attribs_x_ports},
|
|
{"Port 5 Register", NULL, 8, attribs_x_ports},
|
|
{"Port 6 Register", NULL, 8, attribs_x_ports},
|
|
{"Port 7 Register", NULL, 8, attribs_x_ports},
|
|
{"Port 8 Register", NULL, 8, attribs_x_ports},
|
|
{"Port 9 Register", NULL, 8, attribs_x_ports}
|
|
};
|
|
|
|
xHCI_state = (bx_list_c*)SIM->get_param("usb_xhci", SIM->get_bochs_root());
|
|
if (xHCI_state == NULL)
|
|
return -1;
|
|
|
|
main_dialog = gtk_dialog_new();
|
|
switch (type) {
|
|
case USB_DEBUG_COMMAND:
|
|
gtk_window_set_title(GTK_WINDOW(main_dialog), "xHCI Debug Dialog: Break Type: Command Ring");
|
|
break;
|
|
case USB_DEBUG_EVENT:
|
|
gtk_window_set_title(GTK_WINDOW(main_dialog), "xHCI Debug Dialog: Break Type: Event Ring");
|
|
break;
|
|
case USB_DEBUG_FRAME:
|
|
gtk_window_set_title(GTK_WINDOW(main_dialog), "xHCI Debug Dialog: Break Type: Frame");
|
|
break;
|
|
default:
|
|
gtk_window_set_title(GTK_WINDOW(main_dialog), "xHCI Debug Dialog");
|
|
}
|
|
gtk_window_set_default_size(GTK_WINDOW(main_dialog), 600, 500);
|
|
button[0] = gtk_dialog_add_button(GTK_DIALOG(main_dialog), "Continue", GTK_RESPONSE_OK);
|
|
button[1] = gtk_dialog_add_button(GTK_DIALOG(main_dialog), "Quit", GTK_RESPONSE_CANCEL);
|
|
gtk_dialog_set_default_response(GTK_DIALOG(main_dialog), GTK_RESPONSE_OK);
|
|
gtk_window_set_focus(GTK_WINDOW(main_dialog), button[0]);
|
|
mainVbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
|
gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(main_dialog))), mainVbox, TRUE, TRUE, 2);
|
|
|
|
BAhbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
|
gtk_box_pack_start(GTK_BOX(mainVbox), BAhbox, FALSE, FALSE, 2);
|
|
usbdlg_create_label(BAhbox, "xHCI at Base MMIO address", false);
|
|
entry[0] = usbdlg_create_ro_entry(BAhbox, false);
|
|
|
|
hbox[0] = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
|
gtk_box_pack_start(GTK_BOX(mainVbox), hbox[0], TRUE, TRUE, 2);
|
|
hbox[1] = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
|
gtk_box_pack_start(GTK_BOX(mainVbox), hbox[1], TRUE, TRUE, 2);
|
|
for (i = 0; i < 4; i++) {
|
|
vbox[i] = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
|
gtk_box_pack_start(GTK_BOX(hbox[0]), vbox[i], TRUE, TRUE, 2);
|
|
}
|
|
|
|
CRframe = gtk_frame_new("Capability Registers");
|
|
gtk_box_pack_start(GTK_BOX(vbox[0]), CRframe, FALSE, FALSE, 2);
|
|
CRhbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
|
gtk_container_add(GTK_CONTAINER(CRframe), CRhbox);
|
|
CRvbox[0] = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
|
gtk_box_pack_start(GTK_BOX(CRhbox), CRvbox[0], FALSE, FALSE, 2);
|
|
CRvbox[1] = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
|
gtk_box_pack_start(GTK_BOX(CRhbox), CRvbox[1], FALSE, FALSE, 2);
|
|
entry[1] = usbdlg_create_entry_with_label(CRvbox, "Cap Length");
|
|
entry[2] = usbdlg_create_entry_with_label(CRvbox, "HCSParams1");
|
|
entry[3] = usbdlg_create_ro_entry_with_label(CRvbox, "HCSParams2");
|
|
entry[4] = usbdlg_create_entry_with_label(CRvbox, "HCSParams3");
|
|
entry[5] = usbdlg_create_entry_with_label(CRvbox, "HCCParams1");
|
|
entry[6] = usbdlg_create_entry_with_label(CRvbox, "DB Offset");
|
|
entry[7] = usbdlg_create_entry_with_label(CRvbox, "RTS Offset");
|
|
entry[8] = usbdlg_create_entry_with_label(CRvbox, "HCCParams2");
|
|
|
|
ORframe = gtk_frame_new("Operational Registers");
|
|
gtk_box_pack_start(GTK_BOX(vbox[1]), ORframe, FALSE, FALSE, 2);
|
|
ORhbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
|
gtk_container_add(GTK_CONTAINER(ORframe), ORhbox);
|
|
ORvbox[0] = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
|
gtk_box_pack_start(GTK_BOX(ORhbox), ORvbox[0], FALSE, FALSE, 2);
|
|
ORvbox[1] = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
|
gtk_box_pack_start(GTK_BOX(ORhbox), ORvbox[1], FALSE, FALSE, 2);
|
|
entry[9] = usbdlg_create_ro_entry_with_label(ORvbox, "Command");
|
|
entry[10] = usbdlg_create_entry_with_label(ORvbox, "Status");
|
|
entry[11] = usbdlg_create_entry_with_label(ORvbox, "Page Size");
|
|
entry[12] = usbdlg_create_entry_with_label(ORvbox, "Device Notification");
|
|
entry[13] = usbdlg_create_entry_with_label(ORvbox, "Command Ring");
|
|
entry[14] = usbdlg_create_entry_with_label(ORvbox, "Device Context Base");
|
|
entry[15] = usbdlg_create_entry_with_label(ORvbox, "Configure");
|
|
|
|
RTframe = gtk_frame_new("Runtime Registers");
|
|
gtk_box_pack_start(GTK_BOX(vbox[2]), RTframe, FALSE, FALSE, 2);
|
|
RThbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
|
gtk_container_add(GTK_CONTAINER(RTframe), RThbox);
|
|
RTvbox[0] = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
|
gtk_box_pack_start(GTK_BOX(RThbox), RTvbox[0], FALSE, FALSE, 2);
|
|
RTvbox[1] = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
|
gtk_box_pack_start(GTK_BOX(RThbox), RTvbox[1], FALSE, FALSE, 2);
|
|
entry[16] = usbdlg_create_entry_with_label(RTvbox, "Microframe Index");
|
|
|
|
PRframe = gtk_frame_new("Port Registers");
|
|
gtk_box_pack_start(GTK_BOX(hbox[1]), PRframe, FALSE, FALSE, 2);
|
|
PRhbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
|
gtk_container_add(GTK_CONTAINER(PRframe), PRhbox);
|
|
for (i = 0; i < 3; i++) {
|
|
PRvbox[i] = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
|
gtk_box_pack_start(GTK_BOX(PRhbox), PRvbox[i], FALSE, FALSE, 2);
|
|
}
|
|
n_ports = SIM->get_param_num(BXPN_XHCI_N_PORTS)->get();
|
|
for (i = 0; i < n_ports; i++) {
|
|
sprintf(buffer, "Port %d", i);
|
|
entry[i * 2 + 17] = usbdlg_create_entry_with_label(PRvbox, buffer);
|
|
entry[i * 2 + 18] = usbdlg_create_ro_entry_with_label(PRvbox, "Emulation Type");
|
|
button[i + 2] = gtk_button_new_with_label("<>");
|
|
xhci_reg_def[i].entry = entry[i * 2 + 17];
|
|
g_signal_connect(button[i + 2], "clicked", G_CALLBACK(usb_regview_dialog), &xhci_reg_def[i]);
|
|
gtk_box_pack_start(GTK_BOX(PRvbox[2]), button[i + 2], FALSE, FALSE, 2);
|
|
gtk_box_pack_start(GTK_BOX(PRvbox[2]), gtk_label_new(" "), FALSE, FALSE, 8); // spacer
|
|
}
|
|
TVvbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
|
gtk_box_pack_start(GTK_BOX(hbox[1]), TVvbox, TRUE, TRUE, 2);
|
|
FNhbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
|
gtk_box_pack_start(GTK_BOX(TVvbox), FNhbox, FALSE, FALSE, 2);
|
|
FNlabel = usbdlg_create_label(FNhbox, "Ring Address", false);
|
|
entry[n_ports * 2 + 17] = usbdlg_create_ro_entry(FNhbox, false);
|
|
button[12] = gtk_button_new_with_label("View TRB");
|
|
gtk_widget_set_sensitive(button[12], 0);
|
|
gtk_box_pack_start(GTK_BOX(FNhbox), button[12], FALSE, FALSE, 2);
|
|
treeview = gtk_tree_view_new();
|
|
gtk_box_pack_start(GTK_BOX(TVvbox), treeview, TRUE, TRUE, 2);
|
|
|
|
usbdlg_create_apply_button(mainVbox);
|
|
usbdlg_create_debug_flags(vbox[3]);
|
|
// Set values
|
|
pci_bar_address = get_pci_bar_addr((bx_shadow_data_c*)SIM->get_param("hub.pci_conf", xHCI_state), 0);
|
|
sprintf(buffer, "0x%08X", pci_bar_address);
|
|
gtk_entry_set_text(GTK_ENTRY(entry[0]), buffer);
|
|
for (i = 0; i < 8; i++) {
|
|
dword = xhci_read_dword(pci_bar_address + (i * 4));
|
|
sprintf(buffer, "0x%08X", dword);
|
|
gtk_entry_set_text(GTK_ENTRY(entry[i + 1]), buffer);
|
|
g_signal_connect(GTK_EDITABLE(entry[i + 1]), "changed", G_CALLBACK(on_entry_changed), NULL);
|
|
}
|
|
offset = xhci_read_dword(pci_bar_address + 0) & 0xFF;
|
|
|
|
dword = xhci_read_dword(pci_bar_address + offset + 0x00);
|
|
sprintf(buffer, "0x%08X", dword);
|
|
gtk_entry_set_text(GTK_ENTRY(entry[9]), buffer);
|
|
g_signal_connect(GTK_EDITABLE(entry[9]), "changed", G_CALLBACK(on_entry_changed), NULL);
|
|
dword = xhci_read_dword(pci_bar_address + offset + 0x04);
|
|
sprintf(buffer, "0x%08X", dword);
|
|
gtk_entry_set_text(GTK_ENTRY(entry[10]), buffer);
|
|
g_signal_connect(GTK_EDITABLE(entry[10]), "changed", G_CALLBACK(on_entry_changed), NULL);
|
|
dword = xhci_read_dword(pci_bar_address + offset + 0x08);
|
|
sprintf(buffer, "0x%08X", dword);
|
|
gtk_entry_set_text(GTK_ENTRY(entry[11]), buffer);
|
|
g_signal_connect(GTK_EDITABLE(entry[11]), "changed", G_CALLBACK(on_entry_changed), NULL);
|
|
dword = xhci_read_dword(pci_bar_address + offset + 0x14);
|
|
sprintf(buffer, "0x%08X", dword);
|
|
gtk_entry_set_text(GTK_ENTRY(entry[12]), buffer);
|
|
g_signal_connect(GTK_EDITABLE(entry[12]), "changed", G_CALLBACK(on_entry_changed), NULL);
|
|
// we can't read this using DEV_MEM_READ_PHYSICAL since the handler will return zero
|
|
sprintf(buffer, "0x" FMT_ADDRX64, SIM->get_param_num("hub.op_regs.HcCrcr.actual", xHCI_state)->get64());
|
|
gtk_entry_set_text(GTK_ENTRY(entry[13]), buffer);
|
|
g_signal_connect(GTK_EDITABLE(entry[13]), "changed", G_CALLBACK(on_entry_changed), NULL);
|
|
Bit64u qword = xhci_read_dword(pci_bar_address + offset + 0x30) |
|
|
((Bit64u) xhci_read_dword(pci_bar_address + offset + 0x34) << 32);
|
|
sprintf(buffer, "0x" FMT_ADDRX64, qword);
|
|
gtk_entry_set_text(GTK_ENTRY(entry[14]), buffer);
|
|
g_signal_connect(GTK_EDITABLE(entry[14]), "changed", G_CALLBACK(on_entry_changed), NULL);
|
|
dword = xhci_read_dword(pci_bar_address + offset + 0x38);
|
|
sprintf(buffer, "0x%08X", dword);
|
|
gtk_entry_set_text(GTK_ENTRY(entry[15]), buffer);
|
|
g_signal_connect(GTK_EDITABLE(entry[15]), "changed", G_CALLBACK(on_entry_changed), NULL);
|
|
|
|
offset = xhci_read_dword(pci_bar_address + 0x18);
|
|
dword = xhci_read_dword(pci_bar_address + offset + 0);
|
|
sprintf(buffer, "0x%08X", dword);
|
|
gtk_entry_set_text(GTK_ENTRY(entry[16]), buffer);
|
|
g_signal_connect(GTK_EDITABLE(entry[16]), "changed", G_CALLBACK(on_entry_changed), NULL);
|
|
// show up to 10 port register sets
|
|
for (i = 0; i < n_ports; i++) {
|
|
dword = xhci_read_dword(pci_bar_address + XHCI_PORT_SET_OFFSET + (i * 16));
|
|
sprintf(buffer, "0x%08X", dword);
|
|
gtk_entry_set_text(GTK_ENTRY(entry[i * 2 + 17]), buffer);
|
|
g_signal_connect(GTK_EDITABLE(entry[i * 2 + 17]), "changed", G_CALLBACK(on_entry_changed), NULL);
|
|
sprintf(tmpbuf, "port%d.device", i + 1);
|
|
SIM->get_param_enum(tmpbuf, host_param)->dump_param(buffer, COMMON_STR_SIZE, 1);
|
|
gtk_entry_set_text(GTK_ENTRY(entry[i * 2 + 18]), buffer);
|
|
}
|
|
|
|
bool valid = 0;
|
|
switch (type) {
|
|
// a command TRB was placed on the command ring
|
|
case USB_DEBUG_COMMAND:
|
|
gtk_label_set_text(GTK_LABEL(FNlabel), "Command Ring Address");
|
|
RingPtr = SIM->get_param_num("hub.op_regs.HcCrcr.crc", xHCI_state)->get();
|
|
sprintf(buffer, "0x" FMT_ADDRX64, RingPtr);
|
|
gtk_entry_set_text(GTK_ENTRY(entry[n_ports * 2 + 17]), buffer);
|
|
if (RingPtr != 0) {
|
|
gtk_widget_set_sensitive(button[12], 1);
|
|
valid = 1;
|
|
}
|
|
break;
|
|
|
|
// an event TRB was placed on an event ring
|
|
case USB_DEBUG_EVENT:
|
|
gtk_label_set_text(GTK_LABEL(FNlabel), "Event Ring");
|
|
sprintf(buffer, "Interrupter %i", param1);
|
|
gtk_entry_set_text(GTK_ENTRY(entry[n_ports * 2 + 17]), buffer);
|
|
gtk_widget_set_sensitive(button[12], 1);
|
|
valid = 1;
|
|
break;
|
|
|
|
case USB_DEBUG_FRAME:
|
|
|
|
gtk_label_set_text(GTK_LABEL(FNlabel), "SOF Frame Address");
|
|
|
|
break;
|
|
|
|
// first byte (word, dword, qword) of first non-existant port was written to
|
|
case USB_DEBUG_NONEXIST:
|
|
// port reset (non-root reset)
|
|
case USB_DEBUG_RESET:
|
|
// enable changed
|
|
case USB_DEBUG_ENABLE:
|
|
gtk_label_set_text(GTK_LABEL(FNlabel), "None");
|
|
gtk_entry_set_text(GTK_ENTRY(entry[n_ports * 2 + 17]), "None");
|
|
break;
|
|
}
|
|
|
|
if (!valid) {
|
|
gtk_widget_set_sensitive(treeview, 0);
|
|
usbdlg_create_label(TVvbox, "This trigger does not populate the tree view", false);
|
|
} else {
|
|
usbdlg_create_label(TVvbox, "Tree view populated", false);
|
|
}
|
|
// Show dialog
|
|
gtk_widget_show_all(main_dialog);
|
|
ret = gtk_dialog_run(GTK_DIALOG(main_dialog));
|
|
if (ret == GTK_RESPONSE_OK) {
|
|
usbdlg_set_debug_flags();
|
|
}
|
|
gtk_widget_destroy(main_dialog);
|
|
return ret;
|
|
}
|
|
|
|
// USB debug dialog entry point
|
|
|
|
int usb_debug_dialog(int type, int param1, int param2)
|
|
{
|
|
static bool first_call = true;
|
|
int argc = 1, ret;
|
|
char *argv[2], **argvp, buffer[COMMON_STR_SIZE];
|
|
|
|
if (first_call) {
|
|
if (!SIM->is_wx_selected() && !SIM->has_debug_gui()) {
|
|
// you MUST call gtk_init, even with faked arguments, because it inits GDK and Glib
|
|
*buffer = 0; // gtk flames out if you pass in a NULL -- sheesh
|
|
argv[0] = buffer; // so I really do have to fake up an "argv" list
|
|
argv[1] = NULL;
|
|
argvp = argv;
|
|
if (gtk_init_check(&argc, &argvp) == false) {
|
|
fprintf(stderr, "gtk init failed, can not access display?\n");
|
|
return -1;
|
|
}
|
|
MakeGTKthreads();
|
|
}
|
|
first_call = false;
|
|
}
|
|
host_param = SIM->get_param(hc_param_str[usb_debug_type]);
|
|
if (usb_debug_type == USB_DEBUG_UHCI) {
|
|
ret = uhci_debug_dialog(type, param1);
|
|
return (ret == GTK_RESPONSE_OK) ? 0 : -1;
|
|
} else if (usb_debug_type == USB_DEBUG_XHCI) {
|
|
ret = xhci_debug_dialog(type, param1);
|
|
return (ret == GTK_RESPONSE_OK) ? 0 : -1;
|
|
} else {
|
|
GtkWidget* error = gtk_message_dialog_new(
|
|
NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK_CANCEL,
|
|
"GTK version of USB debugger dialog not implemented yet");
|
|
gtk_window_set_title(GTK_WINDOW(error), "WARNING");
|
|
ret = gtk_dialog_run(GTK_DIALOG(error));
|
|
gtk_widget_destroy(error);
|
|
return (ret == GTK_RESPONSE_OK) ? 0 : -1;
|
|
}
|
|
}
|
|
|
|
#endif
|