summaryrefslogtreecommitdiff
path: root/utils/regtools/qeditor
diff options
context:
space:
mode:
Diffstat (limited to 'utils/regtools/qeditor')
-rw-r--r--utils/regtools/qeditor/backend.cpp43
-rw-r--r--utils/regtools/qeditor/backend.h36
-rw-r--r--utils/regtools/qeditor/regtab.cpp117
-rw-r--r--utils/regtools/qeditor/regtab.h19
4 files changed, 207 insertions, 8 deletions
diff --git a/utils/regtools/qeditor/backend.cpp b/utils/regtools/qeditor/backend.cpp
index 75c504a6f6..fa107ec26c 100644
--- a/utils/regtools/qeditor/backend.cpp
+++ b/utils/regtools/qeditor/backend.cpp
@@ -1,6 +1,7 @@
1#include <QFile> 1#include <QFile>
2#include <QTextStream> 2#include <QTextStream>
3#include <QDebug> 3#include <QDebug>
4#include <QFileInfo>
4#include "backend.h" 5#include "backend.h"
5 6
6/** 7/**
@@ -99,9 +100,38 @@ bool FileIoBackend::Reload()
99 else if(ok) 100 else if(ok)
100 m_map[key] = val; 101 m_map[key] = val;
101 } 102 }
103
104 m_readonly = !QFileInfo(file).isWritable();
105 m_dirty = false;
106 return true;
107}
108
109bool FileIoBackend::WriteRegister(const QString& name, soc_word_t value)
110{
111 m_dirty = true;
112 m_map[name] = value;
102 return true; 113 return true;
103} 114}
104 115
116bool FileIoBackend::Commit()
117{
118 if(!m_dirty)
119 return true;
120 QFile file(m_filename);
121 if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text))
122 return false;
123 QTextStream out(&file);
124 out << "HW = " << m_soc << "\n";
125 QMapIterator< QString, soc_word_t > it(m_map);
126 while(it.hasNext())
127 {
128 it.next();
129 out << it.key() << " = " << it.value() << "\n";
130 }
131 out.flush();
132 return file.flush();
133}
134
105#ifdef HAVE_HWSTUB 135#ifdef HAVE_HWSTUB
106/** 136/**
107 * HWStubDevice 137 * HWStubDevice
@@ -195,6 +225,14 @@ bool HWStubDevice::ReadMem(soc_addr_t addr, size_t length, void *buffer)
195 return ret >= 0 && (size_t)ret == length; 225 return ret >= 0 && (size_t)ret == length;
196} 226}
197 227
228bool HWStubDevice::WriteMem(soc_addr_t addr, size_t length, void *buffer)
229{
230 if(!m_hwdev)
231 return false;
232 int ret = hwstub_rw_mem(m_hwdev, 0, addr, buffer, length);
233 return ret >= 0 && (size_t)ret == length;
234}
235
198bool HWStubDevice::IsValid() 236bool HWStubDevice::IsValid()
199{ 237{
200 return m_valid; 238 return m_valid;
@@ -243,6 +281,11 @@ bool HWStubIoBackend::ReadRegister(soc_addr_t addr, soc_word_t& value)
243 return m_dev->ReadMem(addr, sizeof(value), &value); 281 return m_dev->ReadMem(addr, sizeof(value), &value);
244} 282}
245 283
284bool HWStubIoBackend:: WriteRegister(soc_addr_t addr, soc_word_t value)
285{
286 return m_dev->WriteMem(addr, sizeof(value), &value);
287}
288
246bool HWStubIoBackend::Reload() 289bool HWStubIoBackend::Reload()
247{ 290{
248 return true; 291 return true;
diff --git a/utils/regtools/qeditor/backend.h b/utils/regtools/qeditor/backend.h
index 879b88c42c..72a19b6ec1 100644
--- a/utils/regtools/qeditor/backend.h
+++ b/utils/regtools/qeditor/backend.h
@@ -32,6 +32,17 @@ public:
32 virtual bool ReadRegister(soc_addr_t addr, soc_word_t& value) = 0; 32 virtual bool ReadRegister(soc_addr_t addr, soc_word_t& value) = 0;
33 /* reload content (if it makes sense) */ 33 /* reload content (if it makes sense) */
34 virtual bool Reload() = 0; 34 virtual bool Reload() = 0;
35 /* check whether backend supports writing */
36 virtual bool IsReadOnly() = 0;
37 /* write a register by name or address
38 * NOTE: even on a read-only backend, a write is allowed be successful as long
39 * as commit fails */
40 virtual bool WriteRegister(const QString& name, soc_word_t value) = 0;
41 virtual bool WriteRegister(soc_addr_t addr, soc_word_t value) = 0;
42 /* check whether backend contains uncommitted (ie cached) writes */
43 virtual bool IsDirty() = 0;
44 /* commit all writes */
45 virtual bool Commit() = 0;
35}; 46};
36 47
37class DummyIoBackend : public IoBackend 48class DummyIoBackend : public IoBackend
@@ -47,8 +58,17 @@ public:
47 virtual bool ReadRegister(soc_addr_t addr, soc_word_t& value) 58 virtual bool ReadRegister(soc_addr_t addr, soc_word_t& value)
48 { (void) addr; (void) value; return false; } 59 { (void) addr; (void) value; return false; }
49 virtual bool Reload() { return false; } 60 virtual bool Reload() { return false; }
61 virtual bool IsReadOnly() { return true; }
62 virtual bool WriteRegister(const QString& name, soc_word_t value)
63 { (void) name; (void) value; return false; }
64 virtual bool WriteRegister(soc_addr_t addr, soc_word_t value)
65 { (void) addr; (void) value; return false; }
66 virtual bool IsDirty() { return false; }
67 virtual bool Commit() { return false; }
50}; 68};
51 69
70/** NOTE the File backend makes a difference between writes and commits:
71 * a write will *never* touch the underlying file unless it was committed. */
52class FileIoBackend : public IoBackend 72class FileIoBackend : public IoBackend
53{ 73{
54 Q_OBJECT 74 Q_OBJECT
@@ -61,10 +81,18 @@ public:
61 virtual bool ReadRegister(soc_addr_t addr, soc_word_t& value) 81 virtual bool ReadRegister(soc_addr_t addr, soc_word_t& value)
62 { (void) addr; (void) value; return false; } 82 { (void) addr; (void) value; return false; }
63 virtual bool Reload(); 83 virtual bool Reload();
84 virtual bool IsReadOnly() { return m_readonly; }
85 virtual bool WriteRegister(const QString& name, soc_word_t value);
86 virtual bool WriteRegister(soc_addr_t addr, soc_word_t value)
87 { (void) addr; (void) value; return false; }
88 virtual bool IsDirty() { return m_dirty; }
89 virtual bool Commit();
64 90
65protected: 91protected:
66 QString m_filename; 92 QString m_filename;
67 QString m_soc; 93 QString m_soc;
94 bool m_readonly;
95 bool m_dirty;
68 QMap< QString, soc_word_t > m_map; 96 QMap< QString, soc_word_t > m_map;
69}; 97};
70 98
@@ -85,6 +113,7 @@ public:
85 inline struct hwstub_stmp_desc_t GetSTMPInfo() { return m_hwdev_stmp; } 113 inline struct hwstub_stmp_desc_t GetSTMPInfo() { return m_hwdev_stmp; }
86 /* Calls below require the device to be opened */ 114 /* Calls below require the device to be opened */
87 bool ReadMem(soc_addr_t addr, size_t length, void *buffer); 115 bool ReadMem(soc_addr_t addr, size_t length, void *buffer);
116 bool WriteMem(soc_addr_t addr, size_t length, void *buffer);
88 117
89protected: 118protected:
90 bool Probe(); 119 bool Probe();
@@ -98,6 +127,7 @@ protected:
98 struct hwstub_stmp_desc_t m_hwdev_stmp; 127 struct hwstub_stmp_desc_t m_hwdev_stmp;
99}; 128};
100 129
130/** NOTE the HWStub backend is never dirty: all writes are immediately committed */
101class HWStubIoBackend : public IoBackend 131class HWStubIoBackend : public IoBackend
102{ 132{
103 Q_OBJECT 133 Q_OBJECT
@@ -111,6 +141,12 @@ public:
111 { (void) name; (void) value; return false; } 141 { (void) name; (void) value; return false; }
112 virtual bool ReadRegister(soc_addr_t addr, soc_word_t& value); 142 virtual bool ReadRegister(soc_addr_t addr, soc_word_t& value);
113 virtual bool Reload(); 143 virtual bool Reload();
144 virtual bool IsReadOnly() { return false; }
145 virtual bool WriteRegister(const QString& name, soc_word_t value)
146 { (void) name; (void) value; return false; }
147 virtual bool WriteRegister(soc_addr_t addr, soc_word_t value);
148 virtual bool IsDirty() { return false; }
149 virtual bool Commit() { return true; }
114 150
115protected: 151protected:
116 QString m_soc; 152 QString m_soc;
diff --git a/utils/regtools/qeditor/regtab.cpp b/utils/regtools/qeditor/regtab.cpp
index e4adecf203..1e9846ef33 100644
--- a/utils/regtools/qeditor/regtab.cpp
+++ b/utils/regtools/qeditor/regtab.cpp
@@ -17,17 +17,100 @@
17#include "backend.h" 17#include "backend.h"
18#include "analyser.h" 18#include "analyser.h"
19 19
20RegTreeItem::RegTreeItem(const QString& string, int type) 20SocFieldValidator::SocFieldValidator(QObject *parent)
21 :QTreeWidgetItem(QStringList(string), type) 21 :QValidator(parent)
22{ 22{
23 m_field.first_bit = 0;
24 m_field.last_bit = 31;
23} 25}
24 26
25void RegTreeItem::SetPath(int dev_idx, int dev_addr_idx, int reg_idx, int reg_addr_idx) 27SocFieldValidator::SocFieldValidator(const soc_reg_field_t& field, QObject *parent)
28 :QValidator(parent), m_field(field)
26{ 29{
27 m_dev_idx = dev_idx; 30}
28 m_dev_addr_idx = dev_addr_idx; 31
29 m_reg_idx = reg_idx; 32void SocFieldValidator::fixup(QString& input) const
30 m_reg_addr_idx = reg_addr_idx; 33{
34 input = input.trimmed();
35}
36
37QValidator::State SocFieldValidator::validate(QString& input, int& pos) const
38{
39 (void) pos;
40 soc_word_t val;
41 State state = parse(input, val);
42 qDebug() << "validate(" << input << "): " << state;
43 return state;
44}
45
46QValidator::State SocFieldValidator::parse(const QString& input, soc_word_t& val) const
47{
48 // the empty string is all alwats intermediate
49 if(input.size() == 0)
50 return Intermediate;
51 // first check named values
52 State state = Invalid;
53 foreach(const soc_reg_field_value_t& value, m_field.value)
54 {
55 QString name = QString::fromLocal8Bit(value.name.c_str());
56 // cannot be a substring if too long or empty
57 if(input.size() > name.size())
58 continue;
59 // check equal string
60 if(input == name)
61 {
62 state = Acceptable;
63 val = value.value;
64 break;
65 }
66 // check substring
67 if(name.startsWith(input))
68 state = Intermediate;
69 }
70 // early return for exact match
71 if(state == Acceptable)
72 return state;
73 // do a few special cases for convenience
74 if(input.compare("0x", Qt::CaseInsensitive) == 0 ||
75 input.compare("0b", Qt::CaseInsensitive) == 0)
76 return Intermediate;
77 // try by parsing
78 unsigned basis, pos;
79 if(input.size() >= 2 && input.startsWith("0x", Qt::CaseInsensitive))
80 {
81 basis = 16;
82 pos = 2;
83 }
84 else if(input.size() >= 2 && input.startsWith("0b", Qt::CaseInsensitive))
85 {
86 basis = 2;
87 pos = 2;
88 }
89 else if(input.size() >= 2 && input.startsWith("0"))
90 {
91 basis = 8;
92 pos = 1;
93 }
94 else
95 {
96 basis = 10;
97 pos = 0;
98 }
99 bool ok = false;
100 unsigned long v = input.mid(pos).toULong(&ok, basis);
101 // if not ok, return result of name parsing
102 if(!ok)
103 return state;
104 // if ok, check if it fits in the number of bits
105 unsigned nr_bits = m_field.last_bit - m_field.first_bit + 1;
106 unsigned long max = nr_bits == 32 ? 0xffffffff : (1 << nr_bits) - 1;
107 if(v <= max)
108 {
109 val = v;
110 return Acceptable;
111 }
112
113 return state;
31} 114}
32 115
33RegTab::RegTab(Backend *backend) 116RegTab::RegTab(Backend *backend)
@@ -167,6 +250,7 @@ void RegTab::OnDataSelChanged(int index)
167 OnDataSocActivated(m_io_backend->GetSocName()); 250 OnDataSocActivated(m_io_backend->GetSocName());
168 } 251 }
169 Settings::Get()->setValue("regtab/loaddatadir", fd->directory().absolutePath()); 252 Settings::Get()->setValue("regtab/loaddatadir", fd->directory().absolutePath());
253 SetReadOnlyIndicator();
170 } 254 }
171#ifdef HAVE_HWSTUB 255#ifdef HAVE_HWSTUB
172 else if(var == DataSelDevice) 256 else if(var == DataSelDevice)
@@ -189,6 +273,10 @@ void RegTab::OnDataSelChanged(int index)
189 OnDataChanged(); 273 OnDataChanged();
190} 274}
191 275
276void RegTab::SetReadOnlyIndicator()
277{
278}
279
192void RegTab::OnDataChanged() 280void RegTab::OnDataChanged()
193{ 281{
194 OnRegItemChanged(m_reg_tree->currentItem(), m_reg_tree->currentItem()); 282 OnRegItemChanged(m_reg_tree->currentItem(), m_reg_tree->currentItem());
@@ -230,6 +318,8 @@ void RegTab::DisplayRegister(const SocRegRef& ref)
230{ 318{
231 delete m_right_content; 319 delete m_right_content;
232 320
321 bool read_only = m_io_backend->IsReadOnly();
322
233 QVBoxLayout *right_layout = new QVBoxLayout; 323 QVBoxLayout *right_layout = new QVBoxLayout;
234 324
235 const soc_dev_addr_t& dev_addr = ref.GetDevAddr(); 325 const soc_dev_addr_t& dev_addr = ref.GetDevAddr();
@@ -286,9 +376,11 @@ void RegTab::DisplayRegister(const SocRegRef& ref)
286 QLabel *raw_val_name = new QLabel; 376 QLabel *raw_val_name = new QLabel;
287 raw_val_name->setText("Raw value:"); 377 raw_val_name->setText("Raw value:");
288 QLineEdit *raw_val_edit = new QLineEdit; 378 QLineEdit *raw_val_edit = new QLineEdit;
289 raw_val_edit->setReadOnly(true); 379 raw_val_edit->setReadOnly(read_only);
290 raw_val_edit->setText(QString().sprintf("0x%08x", value)); 380 raw_val_edit->setText(QString().sprintf("0x%08x", value));
291 raw_val_edit->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); 381 raw_val_edit->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
382 raw_val_edit->setValidator(new SocFieldValidator(raw_val_edit));
383 connect(raw_val_edit, SIGNAL(returnPressed()), this, SLOT(OnRawRegValueReturnPressed()));
292 raw_val_layout = new QHBoxLayout; 384 raw_val_layout = new QHBoxLayout;
293 raw_val_layout->addStretch(); 385 raw_val_layout->addStretch();
294 raw_val_layout->addWidget(raw_val_name); 386 raw_val_layout->addWidget(raw_val_name);
@@ -445,3 +537,12 @@ void RegTab::OnSocChanged(const QString& soc)
445 FillRegTree(); 537 FillRegTree();
446 FillAnalyserList(); 538 FillAnalyserList();
447} 539}
540
541void RegTab::OnRawRegValueReturnPressed()
542{
543 QObject *obj = sender();
544 QLineEdit *edit = dynamic_cast< QLineEdit* >(obj);
545 const SocFieldValidator *validator = dynamic_cast< const SocFieldValidator* >(edit->validator());
546 soc_word_t val;
547 QValidator::State state = validator->parse(edit->text(), val);
548}
diff --git a/utils/regtools/qeditor/regtab.h b/utils/regtools/qeditor/regtab.h
index 107e4e3986..72f00a31a2 100644
--- a/utils/regtools/qeditor/regtab.h
+++ b/utils/regtools/qeditor/regtab.h
@@ -11,6 +11,7 @@
11#include <QPushButton> 11#include <QPushButton>
12#include <QLabel> 12#include <QLabel>
13#include <QListWidget> 13#include <QListWidget>
14#include <QValidator>
14#include <soc_desc.hpp> 15#include <soc_desc.hpp>
15#include "backend.h" 16#include "backend.h"
16#include "settings.h" 17#include "settings.h"
@@ -52,6 +53,22 @@ private:
52 SocRegRef m_ref; 53 SocRegRef m_ref;
53}; 54};
54 55
56class SocFieldValidator : public QValidator
57{
58 Q_OBJECT
59public:
60 SocFieldValidator(QObject *parent = 0);
61 SocFieldValidator(const soc_reg_field_t& field, QObject *parent = 0);
62
63 virtual void fixup(QString& input) const;
64 virtual State validate(QString& input, int& pos) const;
65 /* validate and return the interpreted value */
66 State parse(const QString& input, soc_word_t& val) const;
67
68protected:
69 soc_reg_field_t m_field;
70};
71
55}; 72};
56 73
57class RegTab : public QSplitter 74class RegTab : public QSplitter
@@ -90,6 +107,7 @@ private slots:
90 void OnDevListChanged(); 107 void OnDevListChanged();
91 void OnDevChanged(int index); 108 void OnDevChanged(int index);
92#endif 109#endif
110 void SetReadOnlyIndicator();
93 void OnSocChanged(const QString& text); 111 void OnSocChanged(const QString& text);
94 void OnSocListChanged(); 112 void OnSocListChanged();
95 void OnRegItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous); 113 void OnRegItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
@@ -99,6 +117,7 @@ private slots:
99 void OnDataSocActivated(const QString&); 117 void OnDataSocActivated(const QString&);
100 void OnAnalyserChanged(QListWidgetItem *current, QListWidgetItem *previous); 118 void OnAnalyserChanged(QListWidgetItem *current, QListWidgetItem *previous);
101 void OnAnalyserClicked(QListWidgetItem *clicked); 119 void OnAnalyserClicked(QListWidgetItem *clicked);
120 void OnRawRegValueReturnPressed();
102}; 121};
103 122
104#endif /* REGTAB_H */ \ No newline at end of file 123#endif /* REGTAB_H */ \ No newline at end of file