summaryrefslogtreecommitdiff
path: root/utils/regtools/qeditor/regtab.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/regtools/qeditor/regtab.cpp')
-rw-r--r--utils/regtools/qeditor/regtab.cpp450
1 files changed, 308 insertions, 142 deletions
diff --git a/utils/regtools/qeditor/regtab.cpp b/utils/regtools/qeditor/regtab.cpp
index 8403a19ea1..4cd4e7b283 100644
--- a/utils/regtools/qeditor/regtab.cpp
+++ b/utils/regtools/qeditor/regtab.cpp
@@ -2,7 +2,6 @@
2 2
3#include <QSplitter> 3#include <QSplitter>
4#include <QVBoxLayout> 4#include <QVBoxLayout>
5#include <QGroupBox>
6#include <QAbstractListModel> 5#include <QAbstractListModel>
7#include <QMessageBox> 6#include <QMessageBox>
8#include <QSizePolicy> 7#include <QSizePolicy>
@@ -14,9 +13,14 @@
14#include <QHeaderView> 13#include <QHeaderView>
15#include <QFileDialog> 14#include <QFileDialog>
16#include <QDebug> 15#include <QDebug>
16#include <QStyle>
17#include "backend.h" 17#include "backend.h"
18#include "analyser.h" 18#include "analyser.h"
19 19
20/**
21 * SocFieldValidator
22 */
23
20SocFieldValidator::SocFieldValidator(QObject *parent) 24SocFieldValidator::SocFieldValidator(QObject *parent)
21 :QValidator(parent) 25 :QValidator(parent)
22{ 26{
@@ -39,7 +43,6 @@ QValidator::State SocFieldValidator::validate(QString& input, int& pos) const
39 (void) pos; 43 (void) pos;
40 soc_word_t val; 44 soc_word_t val;
41 State state = parse(input, val); 45 State state = parse(input, val);
42 qDebug() << "validate(" << input << "): " << state;
43 return state; 46 return state;
44} 47}
45 48
@@ -113,6 +116,289 @@ QValidator::State SocFieldValidator::parse(const QString& input, soc_word_t& val
113 return state; 116 return state;
114} 117}
115 118
119/**
120 * RegLineEdit
121 */
122RegLineEdit::RegLineEdit(QWidget *parent)
123 :QWidget(parent)
124{
125 m_layout = new QHBoxLayout(this);
126 m_button = new QToolButton(this);
127 m_button->setCursor(Qt::ArrowCursor);
128 m_button->setStyleSheet("QToolButton { font-weight: bold; color: white; background: black; }");
129 m_button->setPopupMode(QToolButton::InstantPopup);
130 m_edit = new QLineEdit(this);
131 m_layout->addWidget(m_button);
132 m_layout->addWidget(m_edit);
133 m_menu = new QMenu(this);
134 connect(m_menu->addAction("Write"), SIGNAL(triggered()), this, SLOT(OnWriteAct()));
135 connect(m_menu->addAction("Set"), SIGNAL(triggered()), this, SLOT(OnSetAct()));
136 connect(m_menu->addAction("Clear"), SIGNAL(triggered()), this, SLOT(OnClearAct()));
137 connect(m_menu->addAction("Toggle"), SIGNAL(triggered()), this, SLOT(OnToggleAct()));
138 EnableSCT(false);
139 SetReadOnly(false);
140 ShowMode(true);
141 SetMode(Write);
142}
143
144void RegLineEdit::SetReadOnly(bool ro)
145{
146 m_edit->setReadOnly(ro);
147 m_readonly = ro;
148 ShowMode(!ro);
149}
150
151void RegLineEdit::EnableSCT(bool en)
152{
153 m_has_sct = en;
154 if(!m_has_sct)
155 {
156 m_button->setMenu(0);
157 SetMode(Write);
158 }
159 else
160 m_button->setMenu(m_menu);
161}
162
163RegLineEdit::~RegLineEdit()
164{
165}
166
167QLineEdit *RegLineEdit::GetLineEdit()
168{
169 return m_edit;
170}
171
172void RegLineEdit::ShowMode(bool show)
173{
174 if(show)
175 m_button->show();
176 else
177 m_button->hide();
178}
179
180void RegLineEdit::OnWriteAct()
181{
182 SetMode(Write);
183}
184
185void RegLineEdit::OnSetAct()
186{
187 SetMode(Set);
188}
189
190void RegLineEdit::OnClearAct()
191{
192 SetMode(Clear);
193}
194
195void RegLineEdit::OnToggleAct()
196{
197 SetMode(Toggle);
198}
199
200void RegLineEdit::SetMode(EditMode mode)
201{
202 m_mode = mode;
203 switch(m_mode)
204 {
205 case Write: m_button->setText("WR"); break;
206 case Set: m_button->setText("SET"); break;
207 case Clear: m_button->setText("CLR"); break;
208 case Toggle: m_button->setText("TOG"); break;
209 default: break;
210 }
211}
212
213RegLineEdit::EditMode RegLineEdit::GetMode()
214{
215 return m_mode;
216}
217
218/**
219 * RegDisplayPanel
220 */
221
222RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend, const SocRegRef& reg_ref)
223 :QGroupBox(parent), m_io_backend(io_backend), m_reg(reg_ref)
224{
225 bool read_only = m_io_backend->IsReadOnly();
226
227 QVBoxLayout *right_layout = new QVBoxLayout;
228
229 const soc_dev_addr_t& dev_addr = m_reg.GetDevAddr();
230 const soc_reg_t& reg = m_reg.GetReg();
231 const soc_reg_addr_t& reg_addr = m_reg.GetRegAddr();
232
233 QString reg_name;
234 reg_name.sprintf("HW_%s_%s", dev_addr.name.c_str(), reg_addr.name.c_str());
235 QStringList names;
236 QVector< soc_addr_t > addresses;
237 names.append(reg_name);
238 addresses.append(reg_addr.addr);
239 if(reg.flags & REG_HAS_SCT)
240 {
241 names.append(reg_name + "_SET");
242 names.append(reg_name + "_CLR");
243 names.append(reg_name + "_TOG");
244 addresses.append(reg_addr.addr + 4);
245 addresses.append(reg_addr.addr + 8);
246 addresses.append(reg_addr.addr + 12);
247 }
248
249 QString str;
250 str += "<table align=left>";
251 for(int i = 0; i < names.size(); i++)
252 str += "<tr><td><b>" + names[i] + "</b></td></tr>";
253 str += "</table>";
254 QLabel *label_names = new QLabel;
255 label_names->setTextFormat(Qt::RichText);
256 label_names->setText(str);
257
258 QString str_addr;
259 str_addr += "<table align=left>";
260 for(int i = 0; i < names.size(); i++)
261 str_addr += "<tr><td><b>" + QString().sprintf("0x%03x", addresses[i]) + "</b></td></tr>";
262 str_addr += "</table>";
263 QLabel *label_addr = new QLabel;
264 label_addr->setTextFormat(Qt::RichText);
265 label_addr->setText(str_addr);
266
267 QHBoxLayout *top_layout = new QHBoxLayout;
268 top_layout->addStretch();
269 top_layout->addWidget(label_names);
270 top_layout->addWidget(label_addr);
271 top_layout->addStretch();
272
273 soc_word_t value;
274 BackendHelper helper(m_io_backend, m_reg);
275 bool has_value = helper.ReadRegister(dev_addr.name.c_str(), reg_addr.name.c_str(), value);
276
277 QHBoxLayout *raw_val_layout = 0;
278 if(has_value)
279 {
280 QLabel *raw_val_name = new QLabel;
281 raw_val_name->setText("Raw value:");
282 m_raw_val_edit = new RegLineEdit;
283 m_raw_val_edit->SetReadOnly(read_only);
284 m_raw_val_edit->GetLineEdit()->setText(QString().sprintf("0x%08x", value));
285 m_raw_val_edit->GetLineEdit()->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
286 m_raw_val_edit->GetLineEdit()->setValidator(new SocFieldValidator(m_raw_val_edit));
287 m_raw_val_edit->EnableSCT(!!(reg.flags & REG_HAS_SCT));
288 connect(m_raw_val_edit->GetLineEdit(), SIGNAL(returnPressed()), this, SLOT(OnRawRegValueReturnPressed()));
289 raw_val_layout = new QHBoxLayout;
290 raw_val_layout->addStretch();
291 raw_val_layout->addWidget(raw_val_name);
292 raw_val_layout->addWidget(m_raw_val_edit);
293 raw_val_layout->addStretch();
294 }
295 else
296 m_raw_val_edit = 0;
297
298 QTableWidget *value_table = new QTableWidget;
299 value_table->setRowCount(reg.field.size());
300 value_table->setColumnCount(4);
301 int row = 0;
302 foreach(const soc_reg_field_t& field, reg.field)
303 {
304 QString bits_str;
305 if(field.first_bit == field.last_bit)
306 bits_str.sprintf("%d", field.first_bit);
307 else
308 bits_str.sprintf("%d:%d", field.last_bit, field.first_bit);
309 QTableWidgetItem *item = new QTableWidgetItem(bits_str);
310 item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
311 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
312 value_table->setItem(row, 0, item);
313 item = new QTableWidgetItem(QString(field.name.c_str()));
314 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
315 value_table->setItem(row, 1, item);
316 item = new QTableWidgetItem();
317 if(has_value)
318 {
319 soc_word_t v = (value & field.bitmask()) >> field.first_bit;
320 QString value_name;
321 foreach(const soc_reg_field_value_t& rval, field.value)
322 if(v == rval.value)
323 value_name = rval.name.c_str();
324 const char *fmt = "%lu";
325 // heuristic
326 if((field.last_bit - field.first_bit + 1) > 16)
327 fmt = "0x%lx";
328 item->setText(QString().sprintf(fmt, (unsigned long)v));
329 item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
330
331 if(value_name.size() != 0)
332 {
333 QTableWidgetItem *t = new QTableWidgetItem(value_name);
334 t->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
335 t->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
336 value_table->setItem(row, 3, t);
337 }
338 }
339 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
340 value_table->setItem(row, 2, item);
341 row++;
342 }
343 value_table->setHorizontalHeaderItem(0, new QTableWidgetItem("Bits"));
344 value_table->setHorizontalHeaderItem(1, new QTableWidgetItem("Name"));
345 value_table->setHorizontalHeaderItem(2, new QTableWidgetItem("Value"));
346 value_table->setHorizontalHeaderItem(3, new QTableWidgetItem("Meaning"));
347 value_table->verticalHeader()->setVisible(false);
348 value_table->resizeColumnsToContents();
349 value_table->horizontalHeader()->setStretchLastSection(true);
350 value_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
351
352 right_layout->addLayout(top_layout);
353 if(raw_val_layout)
354 right_layout->addLayout(raw_val_layout);
355 //right_layout->addWidget(bits_label);
356 right_layout->addWidget(value_table);
357 //right_layout->addStretch();
358
359 setTitle("Register Description");
360 setLayout(right_layout);
361 AllowWrite(false);
362}
363
364void RegDisplayPanel::AllowWrite(bool en)
365{
366 m_allow_write = en;
367 if(m_raw_val_edit)
368 m_raw_val_edit->SetReadOnly(m_io_backend->IsReadOnly() || !m_allow_write);
369}
370
371IoBackend::WriteMode RegDisplayPanel::EditModeToWriteMode(RegLineEdit::EditMode mode)
372{
373 switch(mode)
374 {
375 case RegLineEdit::Write: return IoBackend::Write;
376 case RegLineEdit::Set: return IoBackend::Set;
377 case RegLineEdit::Clear: return IoBackend::Clear;
378 case RegLineEdit::Toggle: return IoBackend::Toggle;
379 default: return IoBackend::Write;
380 }
381}
382
383void RegDisplayPanel::OnRawRegValueReturnPressed()
384{
385 soc_word_t val;
386 QLineEdit *edit = m_raw_val_edit->GetLineEdit();
387 const SocFieldValidator *validator = dynamic_cast< const SocFieldValidator *>(edit->validator());
388 QValidator::State state = validator->parse(edit->text(), val);
389 if(state != QValidator::Acceptable)
390 return;
391 IoBackend::WriteMode mode = EditModeToWriteMode(m_raw_val_edit->GetMode());
392 BackendHelper helper(m_io_backend, m_reg);
393 helper.WriteRegister(m_reg.GetDevAddr().name.c_str(), m_reg.GetRegAddr().name.c_str(),
394 val, mode);
395 // FIXME: we should notify the UI to read value back because it has changed
396}
397
398/**
399 * RegTab
400 */
401
116RegTab::RegTab(Backend *backend) 402RegTab::RegTab(Backend *backend)
117 :m_backend(backend) 403 :m_backend(backend)
118{ 404{
@@ -153,15 +439,19 @@ RegTab::RegTab(Backend *backend)
153#endif 439#endif
154 m_data_sel_edit = new QLineEdit; 440 m_data_sel_edit = new QLineEdit;
155 m_data_sel_edit->setReadOnly(true); 441 m_data_sel_edit->setReadOnly(true);
442 m_readonly_check = new QCheckBox("Read-only");
443 m_readonly_check->setCheckState(Qt::Checked);
156 m_data_soc_label = new QLabel; 444 m_data_soc_label = new QLabel;
157 QPushButton *data_sel_reload = new QPushButton; 445 QPushButton *data_sel_reload = new QPushButton;
158 data_sel_reload->setIcon(QIcon::fromTheme("view-refresh")); 446 data_sel_reload->setIcon(QIcon::fromTheme("view-refresh"));
447 data_sel_reload->setToolTip("Reload data");
159 data_sel_layout->addWidget(m_data_selector); 448 data_sel_layout->addWidget(m_data_selector);
160 data_sel_layout->addWidget(m_data_sel_edit); 449 data_sel_layout->addWidget(m_data_sel_edit);
161#ifdef HAVE_HWSTUB 450#ifdef HAVE_HWSTUB
162 m_dev_selector = new QComboBox; 451 m_dev_selector = new QComboBox;
163 data_sel_layout->addWidget(m_dev_selector, 1); 452 data_sel_layout->addWidget(m_dev_selector, 1);
164#endif 453#endif
454 data_sel_layout->addWidget(m_readonly_check);
165 data_sel_layout->addWidget(m_data_soc_label); 455 data_sel_layout->addWidget(m_data_soc_label);
166 data_sel_layout->addWidget(data_sel_reload); 456 data_sel_layout->addWidget(data_sel_reload);
167 data_sel_group->setLayout(data_sel_layout); 457 data_sel_group->setLayout(data_sel_layout);
@@ -199,6 +489,7 @@ RegTab::RegTab(Backend *backend)
199 connect(m_dev_selector, SIGNAL(currentIndexChanged(int)), 489 connect(m_dev_selector, SIGNAL(currentIndexChanged(int)),
200 this, SLOT(OnDevChanged(int))); 490 this, SLOT(OnDevChanged(int)));
201#endif 491#endif
492 connect(m_readonly_check, SIGNAL(clicked(bool)), this, SLOT(OnReadOnlyClicked(bool)));
202 493
203 OnSocListChanged(); 494 OnSocListChanged();
204 OnDataSelChanged(DataSelNothing); 495 OnDataSelChanged(DataSelNothing);
@@ -280,6 +571,8 @@ void RegTab::OnDataSelChanged(int index)
280 571
281void RegTab::SetReadOnlyIndicator() 572void RegTab::SetReadOnlyIndicator()
282{ 573{
574 if(m_io_backend->IsReadOnly())
575 m_readonly_check->setCheckState(Qt::Checked);
283} 576}
284 577
285void RegTab::OnDataChanged() 578void RegTab::OnDataChanged()
@@ -322,140 +615,9 @@ void RegTab::OnAnalyserClicked(QListWidgetItem *current)
322void RegTab::DisplayRegister(const SocRegRef& ref) 615void RegTab::DisplayRegister(const SocRegRef& ref)
323{ 616{
324 delete m_right_content; 617 delete m_right_content;
325 618 RegDisplayPanel *panel = new RegDisplayPanel(this, m_io_backend, ref);
326 bool read_only = m_io_backend->IsReadOnly(); 619 panel->AllowWrite(m_readonly_check->checkState() == Qt::Unchecked);
327 620 m_right_content = panel;
328 QVBoxLayout *right_layout = new QVBoxLayout;
329
330 const soc_dev_addr_t& dev_addr = ref.GetDevAddr();
331 const soc_reg_t& reg = ref.GetReg();
332 const soc_reg_addr_t& reg_addr = ref.GetRegAddr();
333
334 QString reg_name;
335 reg_name.sprintf("HW_%s_%s", dev_addr.name.c_str(), reg_addr.name.c_str());
336 QStringList names;
337 QVector< soc_addr_t > addresses;
338 names.append(reg_name);
339 addresses.append(reg_addr.addr);
340 if(reg.flags & REG_HAS_SCT)
341 {
342 names.append(reg_name + "_SET");
343 names.append(reg_name + "_CLR");
344 names.append(reg_name + "_TOG");
345 addresses.append(reg_addr.addr + 4);
346 addresses.append(reg_addr.addr + 8);
347 addresses.append(reg_addr.addr + 12);
348 }
349
350 QString str;
351 str += "<table align=left>";
352 for(int i = 0; i < names.size(); i++)
353 str += "<tr><td><b>" + names[i] + "</b></td></tr>";
354 str += "</table>";
355 QLabel *label_names = new QLabel;
356 label_names->setTextFormat(Qt::RichText);
357 label_names->setText(str);
358
359 QString str_addr;
360 str_addr += "<table align=left>";
361 for(int i = 0; i < names.size(); i++)
362 str_addr += "<tr><td><b>" + QString().sprintf("0x%03x", addresses[i]) + "</b></td></tr>";
363 str_addr += "</table>";
364 QLabel *label_addr = new QLabel;
365 label_addr->setTextFormat(Qt::RichText);
366 label_addr->setText(str_addr);
367
368 QHBoxLayout *top_layout = new QHBoxLayout;
369 top_layout->addStretch();
370 top_layout->addWidget(label_names);
371 top_layout->addWidget(label_addr);
372 top_layout->addStretch();
373
374 soc_word_t value;
375 BackendHelper helper(m_io_backend, m_cur_soc);
376 bool has_value = helper.ReadRegister(dev_addr.name.c_str(), reg_addr.name.c_str(), value);
377
378 QHBoxLayout *raw_val_layout = 0;
379 if(has_value)
380 {
381 QLabel *raw_val_name = new QLabel;
382 raw_val_name->setText("Raw value:");
383 QLineEdit *raw_val_edit = new QLineEdit;
384 raw_val_edit->setReadOnly(read_only);
385 raw_val_edit->setText(QString().sprintf("0x%08x", value));
386 raw_val_edit->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
387 raw_val_edit->setValidator(new SocFieldValidator(raw_val_edit));
388 connect(raw_val_edit, SIGNAL(returnPressed()), this, SLOT(OnRawRegValueReturnPressed()));
389 raw_val_layout = new QHBoxLayout;
390 raw_val_layout->addStretch();
391 raw_val_layout->addWidget(raw_val_name);
392 raw_val_layout->addWidget(raw_val_edit);
393 raw_val_layout->addStretch();
394 }
395
396 QTableWidget *value_table = new QTableWidget;
397 value_table->setRowCount(reg.field.size());
398 value_table->setColumnCount(4);
399 int row = 0;
400 foreach(const soc_reg_field_t& field, reg.field)
401 {
402 QString bits_str;
403 if(field.first_bit == field.last_bit)
404 bits_str.sprintf("%d", field.first_bit);
405 else
406 bits_str.sprintf("%d:%d", field.last_bit, field.first_bit);
407 QTableWidgetItem *item = new QTableWidgetItem(bits_str);
408 item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
409 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
410 value_table->setItem(row, 0, item);
411 item = new QTableWidgetItem(QString(field.name.c_str()));
412 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
413 value_table->setItem(row, 1, item);
414 item = new QTableWidgetItem();
415 if(has_value)
416 {
417 soc_word_t v = (value & field.bitmask()) >> field.first_bit;
418 QString value_name;
419 foreach(const soc_reg_field_value_t& rval, field.value)
420 if(v == rval.value)
421 value_name = rval.name.c_str();
422 const char *fmt = "%lu";
423 // heuristic
424 if((field.last_bit - field.first_bit + 1) > 16)
425 fmt = "0x%lx";
426 item->setText(QString().sprintf(fmt, (unsigned long)v));
427 item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
428
429 if(value_name.size() != 0)
430 {
431 QTableWidgetItem *t = new QTableWidgetItem(value_name);
432 t->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
433 t->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
434 value_table->setItem(row, 3, t);
435 }
436 }
437 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
438 value_table->setItem(row, 2, item);
439 row++;
440 }
441 value_table->setHorizontalHeaderItem(0, new QTableWidgetItem("Bits"));
442 value_table->setHorizontalHeaderItem(1, new QTableWidgetItem("Name"));
443 value_table->setHorizontalHeaderItem(2, new QTableWidgetItem("Value"));
444 value_table->setHorizontalHeaderItem(3, new QTableWidgetItem("Meaning"));
445 value_table->verticalHeader()->setVisible(false);
446 value_table->resizeColumnsToContents();
447 value_table->horizontalHeader()->setStretchLastSection(true);
448 value_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
449
450 right_layout->addLayout(top_layout);
451 if(raw_val_layout)
452 right_layout->addLayout(raw_val_layout);
453 //right_layout->addWidget(bits_label);
454 right_layout->addWidget(value_table);
455 //right_layout->addStretch();
456
457 m_right_content = new QGroupBox("Register Description");
458 m_right_content->setLayout(right_layout);
459 m_right_panel->addWidget(m_right_content); 621 m_right_panel->addWidget(m_right_content);
460} 622}
461 623
@@ -483,6 +645,7 @@ void RegTab::OnDevListChanged()
483 m_dev_selector->setCurrentIndex(0); 645 m_dev_selector->setCurrentIndex(0);
484 else 646 else
485 SetDataSocName(""); 647 SetDataSocName("");
648 SetReadOnlyIndicator();
486} 649}
487 650
488void RegTab::OnDevChanged(int index) 651void RegTab::OnDevChanged(int index)
@@ -543,11 +706,14 @@ void RegTab::OnSocChanged(const QString& soc)
543 FillAnalyserList(); 706 FillAnalyserList();
544} 707}
545 708
546void RegTab::OnRawRegValueReturnPressed() 709void RegTab::OnReadOnlyClicked(bool checked)
547{ 710{
548 QObject *obj = sender(); 711 if(m_io_backend->IsReadOnly())
549 QLineEdit *edit = dynamic_cast< QLineEdit* >(obj); 712 return SetReadOnlyIndicator();
550 const SocFieldValidator *validator = dynamic_cast< const SocFieldValidator* >(edit->validator()); 713 if(m_right_content == 0)
551 soc_word_t val; 714 return;
552 QValidator::State state = validator->parse(edit->text(), val); 715 RegDisplayPanel *panel = dynamic_cast< RegDisplayPanel* >(m_right_content);
716 if(panel == 0)
717 return;
718 panel->AllowWrite(!checked);
553} 719}