nkeynes@31: /** nkeynes@586: * $Id$ nkeynes@31: * nkeynes@31: * Implements the MMIO register viewing window nkeynes@31: * nkeynes@31: * Copyright (c) 2005 Nathan Keynes. nkeynes@31: * nkeynes@31: * This program is free software; you can redistribute it and/or modify nkeynes@31: * it under the terms of the GNU General Public License as published by nkeynes@31: * the Free Software Foundation; either version 2 of the License, or nkeynes@31: * (at your option) any later version. nkeynes@31: * nkeynes@31: * This program is distributed in the hope that it will be useful, nkeynes@31: * but WITHOUT ANY WARRANTY; without even the implied warranty of nkeynes@31: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nkeynes@31: * GNU General Public License for more details. nkeynes@31: */ nkeynes@31: nkeynes@2: #include nkeynes@484: #include nkeynes@537: #include "gtkui/gtkui.h" nkeynes@2: #include "mem.h" nkeynes@2: #include "mmio.h" nkeynes@2: nkeynes@457: nkeynes@457: struct mmio_window_info { nkeynes@457: GtkWidget *window; nkeynes@457: GtkWidget *notebook; nkeynes@457: }; nkeynes@2: nkeynes@2: static void printbits( char *out, int nbits, uint32_t value ) nkeynes@2: { nkeynes@2: if( nbits < 32 ) { nkeynes@2: int i; nkeynes@2: for( i=32; i>nbits; i-- ) { nkeynes@2: if( !(i % 8) ) *out++ = ' '; nkeynes@2: *out++ = ' '; nkeynes@2: } nkeynes@2: } nkeynes@2: while( nbits > 0 ) { nkeynes@2: *out++ = (value&(1<<--nbits) ? '1' : '0'); nkeynes@2: if( !(nbits % 8) ) *out++ = ' '; nkeynes@2: } nkeynes@2: *out = '\0'; nkeynes@2: } nkeynes@2: nkeynes@2: static void printhex( char *out, int nbits, uint32_t value ) nkeynes@2: { nkeynes@2: char tmp[10], *p = tmp; nkeynes@2: int i; nkeynes@2: nkeynes@2: sprintf( tmp, "%08X", value ); nkeynes@2: for( i=32; i>0; i-=4, p++ ) { nkeynes@2: if( i <= nbits ) *out++ = *p; nkeynes@2: else *out++ = ' '; nkeynes@2: } nkeynes@2: *out = '\0'; nkeynes@2: } nkeynes@736: nkeynes@457: nkeynes@457: nkeynes@457: nkeynes@457: gboolean nkeynes@457: on_mmio_delete_event (GtkWidget *widget, nkeynes@736: GdkEvent *event, nkeynes@736: gpointer user_data) nkeynes@457: { nkeynes@457: gtk_widget_hide(widget); nkeynes@457: return TRUE; nkeynes@457: } nkeynes@457: nkeynes@457: nkeynes@457: void on_mmio_close_clicked( GtkButton *button, gpointer user_data) nkeynes@457: { nkeynes@457: gtk_widget_hide( ((mmio_window_t)user_data)->window ); nkeynes@457: } nkeynes@457: nkeynes@457: nkeynes@457: void on_trace_button_toggled (GtkToggleButton *button, nkeynes@736: gpointer user_data) nkeynes@457: { nkeynes@457: struct mmio_region *io_rgn = (struct mmio_region *)user_data; nkeynes@457: gboolean isActive = gtk_toggle_button_get_active(button); nkeynes@457: if( io_rgn != NULL ) { nkeynes@736: io_rgn->trace_flag = isActive ? 1 : 0; nkeynes@457: } nkeynes@457: } nkeynes@457: nkeynes@457: static GtkCList *mmio_window_add_page( mmio_window_t mmio, char *name, struct mmio_region *io_rgn ) nkeynes@2: { nkeynes@2: GtkCList *list; nkeynes@2: GtkWidget *scroll; nkeynes@2: GtkWidget *tab; nkeynes@238: GtkCheckButton *trace_button; nkeynes@238: GtkVBox *vbox; nkeynes@2: nkeynes@2: scroll = gtk_scrolled_window_new(NULL, NULL); nkeynes@2: gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(scroll), nkeynes@2: GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS ); nkeynes@2: list = GTK_CLIST(gtk_clist_new(5)); nkeynes@45: gtk_clist_set_column_width(list, 0, 70); nkeynes@45: gtk_clist_set_column_width(list, 1, 75); nkeynes@45: gtk_clist_set_column_width(list, 2, 70); nkeynes@45: gtk_clist_set_column_width(list, 3, 280); nkeynes@2: gtk_clist_set_column_width(list, 4, 160); nkeynes@2: gtk_clist_set_column_justification(list, 0, GTK_JUSTIFY_CENTER ); nkeynes@2: gtk_clist_set_column_justification(list, 2, GTK_JUSTIFY_CENTER ); nkeynes@2: gtk_clist_set_column_justification(list, 3, GTK_JUSTIFY_CENTER ); nkeynes@508: gtk_clist_set_column_title(list, 0, _("Address")); nkeynes@508: gtk_clist_set_column_title(list, 1, _("Register")); nkeynes@508: gtk_clist_set_column_title(list, 2, _("Value")); nkeynes@508: gtk_clist_set_column_title(list, 3, _("Bit Pattern")); nkeynes@508: gtk_clist_set_column_title(list, 4, _("Description")); nkeynes@2: gtk_clist_column_titles_show(list); nkeynes@435: gtk_widget_modify_font( GTK_WIDGET(list), gui_fixed_font ); nkeynes@2: tab = gtk_label_new(_(name)); nkeynes@2: gtk_container_add( GTK_CONTAINER(scroll), GTK_WIDGET(list) ); nkeynes@736: nkeynes@429: vbox = GTK_VBOX(gtk_vbox_new( FALSE, 0 )); nkeynes@238: gtk_container_add( GTK_CONTAINER(vbox), GTK_WIDGET(scroll) ); nkeynes@238: nkeynes@508: trace_button = GTK_CHECK_BUTTON(gtk_check_button_new_with_label(_("Trace access"))); nkeynes@586: if( io_rgn != NULL ) { nkeynes@736: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(trace_button), nkeynes@736: io_rgn->trace_flag ? TRUE : FALSE); nkeynes@586: } nkeynes@238: gtk_container_add( GTK_CONTAINER(vbox), GTK_WIDGET(trace_button) ); nkeynes@238: gtk_box_set_child_packing( GTK_BOX(vbox), GTK_WIDGET(trace_button), nkeynes@736: FALSE, FALSE, 0, GTK_PACK_START ); nkeynes@457: gtk_notebook_append_page( GTK_NOTEBOOK(mmio->notebook), GTK_WIDGET(vbox), tab ); nkeynes@457: gtk_object_set_data( GTK_OBJECT(mmio->window), name, list ); nkeynes@238: g_signal_connect ((gpointer) trace_button, "toggled", nkeynes@736: G_CALLBACK (on_trace_button_toggled), nkeynes@736: io_rgn); nkeynes@2: return list; nkeynes@2: } nkeynes@2: nkeynes@457: nkeynes@457: nkeynes@457: mmio_window_t mmio_window_new( const gchar *title ) nkeynes@457: { nkeynes@457: mmio_window_t mmio = g_malloc0( sizeof(struct mmio_window_info) ); nkeynes@736: nkeynes@457: int i, j; nkeynes@457: GtkCList *all_list; nkeynes@457: GtkWidget *vbox1; nkeynes@457: GtkWidget *hbuttonbox1; nkeynes@457: GtkWidget *mmr_close; nkeynes@457: nkeynes@457: mmio->window = gtk_window_new (GTK_WINDOW_TOPLEVEL); nkeynes@457: gtk_window_set_title (GTK_WINDOW (mmio->window), title); nkeynes@457: gtk_window_set_default_size (GTK_WINDOW (mmio->window), 600, 600); nkeynes@457: nkeynes@457: vbox1 = gtk_vbox_new (FALSE, 0); nkeynes@457: gtk_container_add (GTK_CONTAINER (mmio->window), vbox1); nkeynes@457: nkeynes@457: mmio->notebook = gtk_notebook_new (); nkeynes@457: gtk_box_pack_start (GTK_BOX (vbox1), mmio->notebook, TRUE, TRUE, 0); nkeynes@457: gtk_notebook_set_tab_pos (GTK_NOTEBOOK (mmio->notebook), GTK_POS_LEFT); nkeynes@457: nkeynes@457: hbuttonbox1 = gtk_hbutton_box_new (); nkeynes@457: gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox1, FALSE, TRUE, 0); nkeynes@457: gtk_box_set_spacing (GTK_BOX (hbuttonbox1), 30); nkeynes@736: nkeynes@457: mmr_close = gtk_button_new_with_mnemonic (_("Close")); nkeynes@457: gtk_container_add (GTK_CONTAINER (hbuttonbox1), mmr_close); nkeynes@457: GTK_WIDGET_SET_FLAGS (mmr_close, GTK_CAN_DEFAULT); nkeynes@457: nkeynes@457: /* Add the mmio register data */ nkeynes@457: all_list = mmio_window_add_page( mmio, "All", NULL ); nkeynes@457: for( i=0; i < num_io_rgns; i++ ) { nkeynes@457: GtkCList *list = mmio_window_add_page( mmio, io_rgn[i]->id, io_rgn[i] ); nkeynes@457: for( j=0; io_rgn[i]->ports[j].id != NULL; j++ ) { nkeynes@457: int sz = io_rgn[i]->ports[j].width; nkeynes@457: char addr[10], data[10], bits[40]; nkeynes@457: char *arr[] = { addr, io_rgn[i]->ports[j].id, data, bits, nkeynes@736: io_rgn[i]->ports[j].desc }; nkeynes@457: sprintf( addr, "%08X", nkeynes@457: io_rgn[i]->base + io_rgn[i]->ports[j].offset ); nkeynes@457: printhex( data, sz, *io_rgn[i]->ports[j].val ); nkeynes@457: printbits( bits, io_rgn[i]->ports[j].width, nkeynes@457: *io_rgn[i]->ports[j].val ); nkeynes@457: gtk_clist_append( list, arr ); nkeynes@457: gtk_clist_append( all_list, arr ); nkeynes@457: } nkeynes@457: } nkeynes@736: nkeynes@457: g_signal_connect ((gpointer) mmio->window, "delete_event", nkeynes@736: G_CALLBACK (on_mmio_delete_event), nkeynes@736: NULL); nkeynes@457: g_signal_connect ((gpointer) mmr_close, "clicked", nkeynes@736: G_CALLBACK (on_mmio_close_clicked), nkeynes@736: mmio); nkeynes@457: nkeynes@457: gtk_widget_show_all( mmio->window ); nkeynes@457: return mmio; nkeynes@457: } nkeynes@736: nkeynes@457: void mmio_window_update( mmio_window_t mmio ) nkeynes@2: { nkeynes@2: int i,j, count = 0; nkeynes@2: GtkCList *page, *all_page; nkeynes@2: char data[10], bits[40]; nkeynes@2: nkeynes@457: all_page = GTK_CLIST(gtk_object_get_data( GTK_OBJECT(mmio->window), "All" )); nkeynes@736: nkeynes@57: for( i=0; i < num_io_rgns; i++ ) { nkeynes@457: page = GTK_CLIST(gtk_object_get_data( GTK_OBJECT(mmio->window), nkeynes@736: io_rgn[i]->id )); nkeynes@2: for( j=0; io_rgn[i]->ports[j].id != NULL; j++ ) { nkeynes@2: if( *io_rgn[i]->ports[j].val != nkeynes@2: *(uint32_t *)(io_rgn[i]->save_mem+io_rgn[i]->ports[j].offset)){ nkeynes@2: int sz = io_rgn[i]->ports[j].width; nkeynes@2: /* Changed */ nkeynes@2: printhex( data, sz, *io_rgn[i]->ports[j].val ); nkeynes@2: printbits( bits, sz, *io_rgn[i]->ports[j].val ); nkeynes@736: nkeynes@2: gtk_clist_set_text( page, j, 2, data ); nkeynes@2: gtk_clist_set_text( page, j, 3, bits ); nkeynes@435: gtk_clist_set_foreground( page, j, &gui_colour_changed ); nkeynes@736: nkeynes@2: gtk_clist_set_text( all_page, count, 2, data ); nkeynes@2: gtk_clist_set_text( all_page, count, 3, bits ); nkeynes@435: gtk_clist_set_foreground( all_page, count, &gui_colour_changed ); nkeynes@736: nkeynes@2: } else { nkeynes@435: gtk_clist_set_foreground( page, j, &gui_colour_normal ); nkeynes@435: gtk_clist_set_foreground( all_page, count, &gui_colour_normal ); nkeynes@2: } nkeynes@2: count++; nkeynes@2: } nkeynes@796: memcpy( io_rgn[i]->save_mem, io_rgn[i]->mem, LXDREAM_PAGE_SIZE ); nkeynes@2: } nkeynes@2: } nkeynes@2: nkeynes@457: void mmio_window_show( mmio_window_t mmio, gboolean show ) nkeynes@2: { nkeynes@457: if( show ) { nkeynes@736: gtk_widget_show( mmio->window ); nkeynes@457: } else { nkeynes@736: gtk_widget_hide( mmio->window ); nkeynes@2: } nkeynes@2: } nkeynes@2: