diff options
Diffstat (limited to 'utils/regtools/qeditor')
-rw-r--r-- | utils/regtools/qeditor/backend.cpp | 317 | ||||
-rw-r--r-- | utils/regtools/qeditor/backend.h | 113 | ||||
-rw-r--r-- | utils/regtools/qeditor/main.cpp | 7 | ||||
-rw-r--r-- | utils/regtools/qeditor/qeditor.pro | 14 | ||||
-rw-r--r-- | utils/regtools/qeditor/regtab.cpp | 65 | ||||
-rw-r--r-- | utils/regtools/qeditor/regtab.h | 11 |
6 files changed, 486 insertions, 41 deletions
diff --git a/utils/regtools/qeditor/backend.cpp b/utils/regtools/qeditor/backend.cpp index e011965bd2..d2b75be701 100644 --- a/utils/regtools/qeditor/backend.cpp +++ b/utils/regtools/qeditor/backend.cpp | |||
@@ -3,6 +3,10 @@ | |||
3 | #include <QDebug> | 3 | #include <QDebug> |
4 | #include "backend.h" | 4 | #include "backend.h" |
5 | 5 | ||
6 | /** | ||
7 | * Backend | ||
8 | */ | ||
9 | |||
6 | Backend::Backend() | 10 | Backend::Backend() |
7 | { | 11 | { |
8 | } | 12 | } |
@@ -43,9 +47,16 @@ IoBackend *Backend::CreateDummyIoBackend() | |||
43 | return new DummyIoBackend(); | 47 | return new DummyIoBackend(); |
44 | } | 48 | } |
45 | 49 | ||
46 | IoBackend::IoBackend() | 50 | #ifdef HAVE_HWSTUB |
51 | IoBackend *Backend::CreateHWStubIoBackend(HWStubDevice *dev) | ||
47 | { | 52 | { |
53 | return new HWStubIoBackend(dev); | ||
48 | } | 54 | } |
55 | #endif | ||
56 | |||
57 | /** | ||
58 | * FileIoBackend | ||
59 | */ | ||
49 | 60 | ||
50 | FileIoBackend::FileIoBackend(const QString& filename) | 61 | FileIoBackend::FileIoBackend(const QString& filename) |
51 | { | 62 | { |
@@ -91,27 +102,230 @@ bool FileIoBackend::Reload() | |||
91 | return true; | 102 | return true; |
92 | } | 103 | } |
93 | 104 | ||
94 | DummyIoBackend::DummyIoBackend() | 105 | #ifdef HAVE_HWSTUB |
106 | /** | ||
107 | * HWStubDevice | ||
108 | */ | ||
109 | HWStubDevice::HWStubDevice(struct libusb_device *dev) | ||
95 | { | 110 | { |
111 | libusb_ref_device(dev); | ||
112 | m_dev = dev; | ||
113 | m_handle = 0; | ||
114 | m_hwdev = 0; | ||
115 | m_valid = Probe(); | ||
96 | } | 116 | } |
97 | 117 | ||
98 | QString DummyIoBackend::GetSocName() | 118 | HWStubDevice::~HWStubDevice() |
99 | { | 119 | { |
100 | return ""; | 120 | Close(); |
121 | libusb_unref_device(m_dev); | ||
101 | } | 122 | } |
102 | 123 | ||
103 | bool DummyIoBackend::ReadRegister(const QString& name, soc_word_t& value) | 124 | int HWStubDevice::GetBusNumber() |
104 | { | 125 | { |
105 | (void) name; | 126 | return libusb_get_bus_number(m_dev); |
106 | (void) value; | 127 | } |
128 | |||
129 | int HWStubDevice::GetDevAddress() | ||
130 | { | ||
131 | return libusb_get_device_address(m_dev); | ||
132 | } | ||
133 | |||
134 | bool HWStubDevice::Probe() | ||
135 | { | ||
136 | struct libusb_device_descriptor desc; | ||
137 | if(libusb_get_device_descriptor(m_dev, &desc)) | ||
138 | return false; | ||
139 | if(desc.idVendor != HWSTUB_USB_VID || desc.idProduct != HWSTUB_USB_PID) | ||
140 | return false; | ||
141 | if(!Open()) | ||
142 | return false; | ||
143 | int ret = hwstub_get_desc(m_hwdev, HWSTUB_DT_VERSION, &m_hwdev_ver, sizeof(m_hwdev_ver)); | ||
144 | if(ret != sizeof(m_hwdev_ver)) | ||
145 | goto Lerr; | ||
146 | if(m_hwdev_ver.bMajor != HWSTUB_VERSION_MAJOR || m_hwdev_ver.bMinor < HWSTUB_VERSION_MINOR) | ||
147 | goto Lerr; | ||
148 | // get target | ||
149 | ret = hwstub_get_desc(m_hwdev, HWSTUB_DT_TARGET, &m_hwdev_target, sizeof(m_hwdev_target)); | ||
150 | if(ret != sizeof(m_hwdev_target)) | ||
151 | goto Lerr; | ||
152 | // get STMP information | ||
153 | if(m_hwdev_target.dID == HWSTUB_TARGET_STMP) | ||
154 | { | ||
155 | ret = hwstub_get_desc(m_hwdev, HWSTUB_DT_STMP, &m_hwdev_stmp, sizeof(m_hwdev_stmp)); | ||
156 | if(ret != sizeof(m_hwdev_stmp)) | ||
157 | goto Lerr; | ||
158 | } | ||
159 | Close(); | ||
160 | return true; | ||
161 | |||
162 | Lerr: | ||
163 | Close(); | ||
107 | return false; | 164 | return false; |
108 | } | 165 | } |
109 | 166 | ||
110 | bool DummyIoBackend::Reload() | 167 | bool HWStubDevice::Open() |
168 | { | ||
169 | if(libusb_open(m_dev, &m_handle)) | ||
170 | return false; | ||
171 | m_hwdev = hwstub_open(m_handle); | ||
172 | if(m_hwdev == 0) | ||
173 | { | ||
174 | libusb_close(m_handle); | ||
175 | return false; | ||
176 | } | ||
177 | return true; | ||
178 | } | ||
179 | |||
180 | void HWStubDevice::Close() | ||
181 | { | ||
182 | if(m_hwdev) | ||
183 | hwstub_release(m_hwdev); | ||
184 | m_hwdev = 0; | ||
185 | if(m_handle) | ||
186 | libusb_close(m_handle); | ||
187 | m_handle = 0; | ||
188 | } | ||
189 | |||
190 | bool HWStubDevice::ReadMem(soc_addr_t addr, size_t length, void *buffer) | ||
191 | { | ||
192 | if(!m_hwdev) | ||
193 | return false; | ||
194 | int ret = hwstub_rw_mem(m_hwdev, 1, addr, buffer, length); | ||
195 | return ret >= 0 && (size_t)ret == length; | ||
196 | } | ||
197 | |||
198 | bool HWStubDevice::IsValid() | ||
199 | { | ||
200 | return m_valid; | ||
201 | } | ||
202 | |||
203 | |||
204 | /** | ||
205 | * HWStubIoBackend | ||
206 | */ | ||
207 | |||
208 | HWStubIoBackend::HWStubIoBackend(HWStubDevice *dev) | ||
209 | { | ||
210 | m_dev = dev; | ||
211 | m_dev->Open(); | ||
212 | struct hwstub_target_desc_t target = m_dev->GetTargetInfo(); | ||
213 | if(target.dID == HWSTUB_TARGET_STMP) | ||
214 | { | ||
215 | struct hwstub_stmp_desc_t stmp = m_dev->GetSTMPInfo(); | ||
216 | if(stmp.wChipID == 0x3780) | ||
217 | m_soc = "imx233"; | ||
218 | else if(stmp.wChipID >= 0x3700 && stmp.wChipID < 0x3780) | ||
219 | m_soc = "stmp3700"; | ||
220 | else if(stmp.wChipID >= 0x3600 && stmp.wChipID < 0x3700) | ||
221 | m_soc = "stmp3600"; | ||
222 | else | ||
223 | m_soc = QString("stmp%1").arg(stmp.wChipID, 4, 16, QChar('0')); | ||
224 | } | ||
225 | else if(target.dID == HWSTUB_TARGET_RK27) | ||
226 | m_soc = "rk27x"; | ||
227 | else | ||
228 | m_soc = target.bName; | ||
229 | } | ||
230 | |||
231 | QString HWStubIoBackend::GetSocName() | ||
232 | { | ||
233 | return m_soc; | ||
234 | } | ||
235 | |||
236 | HWStubIoBackend::~HWStubIoBackend() | ||
237 | { | ||
238 | m_dev->Close(); | ||
239 | } | ||
240 | |||
241 | bool HWStubIoBackend::ReadRegister(soc_addr_t addr, soc_word_t& value) | ||
242 | { | ||
243 | return m_dev->ReadMem(addr, sizeof(value), &value); | ||
244 | } | ||
245 | |||
246 | bool HWStubIoBackend::Reload() | ||
111 | { | 247 | { |
112 | return true; | 248 | return true; |
113 | } | 249 | } |
114 | 250 | ||
251 | /** | ||
252 | * HWStubBackendHelper | ||
253 | */ | ||
254 | HWStubBackendHelper::HWStubBackendHelper() | ||
255 | { | ||
256 | libusb_init(NULL); | ||
257 | #ifdef LIBUSB_NO_HOTPLUG | ||
258 | m_hotplug = false; | ||
259 | #else | ||
260 | m_hotplug = libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG); | ||
261 | if(m_hotplug) | ||
262 | { | ||
263 | m_hotplug = LIBUSB_SUCCESS == libusb_hotplug_register_callback( | ||
264 | NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, | ||
265 | LIBUSB_HOTPLUG_ENUMERATE, HWSTUB_USB_VID, HWSTUB_USB_PID, HWSTUB_CLASS, | ||
266 | &HWStubBackendHelper::HotPlugCallback, reinterpret_cast< void* >(this), &m_hotplug_handle); | ||
267 | } | ||
268 | #endif | ||
269 | } | ||
270 | |||
271 | HWStubBackendHelper::~HWStubBackendHelper() | ||
272 | { | ||
273 | #ifndef LIBUSB_NO_HOTPLUG | ||
274 | if(m_hotplug) | ||
275 | libusb_hotplug_deregister_callback(NULL, m_hotplug_handle); | ||
276 | #endif | ||
277 | } | ||
278 | |||
279 | QList< HWStubDevice* > HWStubBackendHelper::GetDevList() | ||
280 | { | ||
281 | QList< HWStubDevice* > list; | ||
282 | libusb_device **dev_list; | ||
283 | ssize_t cnt = libusb_get_device_list(NULL, &dev_list); | ||
284 | for(int i = 0; i < cnt; i++) | ||
285 | { | ||
286 | HWStubDevice *dev = new HWStubDevice(dev_list[i]); | ||
287 | /* filter out non-hwstub devices */ | ||
288 | if(dev->IsValid()) | ||
289 | list.push_back(dev); | ||
290 | else | ||
291 | delete dev; | ||
292 | } | ||
293 | libusb_free_device_list(dev_list, 1); | ||
294 | return list; | ||
295 | } | ||
296 | |||
297 | #ifndef LIBUSB_NO_HOTPLUG | ||
298 | void HWStubBackendHelper::OnHotPlug(bool arrived, struct libusb_device *dev) | ||
299 | { | ||
300 | /* signal it */ | ||
301 | emit OnDevListChanged(arrived, dev); | ||
302 | } | ||
303 | |||
304 | int HWStubBackendHelper::HotPlugCallback(struct libusb_context *ctx, struct libusb_device *dev, | ||
305 | libusb_hotplug_event event, void *user_data) | ||
306 | { | ||
307 | HWStubBackendHelper *helper = reinterpret_cast< HWStubBackendHelper* >(user_data); | ||
308 | switch(event) | ||
309 | { | ||
310 | case LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED: helper->OnHotPlug(true, dev); break; | ||
311 | case LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT: helper->OnHotPlug(false, dev); break; | ||
312 | default: break; | ||
313 | } | ||
314 | return 0; | ||
315 | } | ||
316 | #endif | ||
317 | |||
318 | bool HWStubBackendHelper::HasHotPlugSupport() | ||
319 | { | ||
320 | return m_hotplug; | ||
321 | } | ||
322 | |||
323 | #endif | ||
324 | |||
325 | /** | ||
326 | * BackendHelper | ||
327 | */ | ||
328 | |||
115 | BackendHelper::BackendHelper(IoBackend *io_backend, const soc_t& soc) | 329 | BackendHelper::BackendHelper(IoBackend *io_backend, const soc_t& soc) |
116 | :m_io_backend(io_backend), m_soc(soc) | 330 | :m_io_backend(io_backend), m_soc(soc) |
117 | { | 331 | { |
@@ -119,38 +333,87 @@ BackendHelper::BackendHelper(IoBackend *io_backend, const soc_t& soc) | |||
119 | 333 | ||
120 | bool BackendHelper::ReadRegister(const QString& dev, const QString& reg, soc_word_t& v) | 334 | bool BackendHelper::ReadRegister(const QString& dev, const QString& reg, soc_word_t& v) |
121 | { | 335 | { |
122 | return m_io_backend->ReadRegister("HW." + dev + "." + reg, v); | 336 | if(m_io_backend->SupportAccess(IoBackend::ByName)) |
337 | return m_io_backend->ReadRegister("HW." + dev + "." + reg, v); | ||
338 | if(m_io_backend->SupportAccess(IoBackend::ByAddress)) | ||
339 | { | ||
340 | soc_addr_t addr; | ||
341 | if(GetRegisterAddress(dev, reg, addr)) | ||
342 | return m_io_backend->ReadRegister(addr, v); | ||
343 | } | ||
344 | return false; | ||
123 | } | 345 | } |
124 | 346 | ||
125 | bool BackendHelper::ReadRegisterField(const QString& dev, const QString& reg, | 347 | |
126 | const QString& field, soc_word_t& v) | 348 | bool BackendHelper::GetDeviceDesc(const QString& dev, soc_dev_t& dev_desc, size_t& index) |
127 | { | 349 | { |
128 | soc_dev_t *sdev = 0; | ||
129 | for(size_t i = 0; i < m_soc.dev.size(); i++) | 350 | for(size_t i = 0; i < m_soc.dev.size(); i++) |
130 | { | 351 | { |
131 | for(size_t j = 0; j < m_soc.dev[i].addr.size(); j++) | 352 | for(size_t j = 0; j < m_soc.dev[i].addr.size(); j++) |
132 | if(m_soc.dev[i].addr[j].name.c_str() == dev) | 353 | if(m_soc.dev[i].addr[j].name.c_str() == dev) |
133 | sdev = &m_soc.dev[i]; | 354 | { |
355 | dev_desc = m_soc.dev[i]; | ||
356 | index = j; | ||
357 | return true; | ||
358 | } | ||
134 | } | 359 | } |
135 | if(sdev == 0) | 360 | return false; |
136 | return false; | 361 | } |
137 | soc_reg_t *sreg = 0; | 362 | |
138 | for(size_t i = 0; i < sdev->reg.size(); i++) | 363 | bool BackendHelper::GetRegisterDesc(const soc_dev_t& dev, const QString& reg, |
364 | soc_reg_t& reg_desc, size_t& index) | ||
365 | { | ||
366 | for(size_t i = 0; i < dev.reg.size(); i++) | ||
139 | { | 367 | { |
140 | for(size_t j = 0; j < sdev->reg[i].addr.size(); j++) | 368 | for(size_t j = 0; j < dev.reg[i].addr.size(); j++) |
141 | if(sdev->reg[i].addr[j].name.c_str() == reg) | 369 | if(dev.reg[i].addr[j].name.c_str() == reg) |
142 | sreg = &sdev->reg[i]; | 370 | { |
371 | index = j; | ||
372 | reg_desc = dev.reg[i]; | ||
373 | return true; | ||
374 | } | ||
143 | } | 375 | } |
144 | if(sreg == 0) | 376 | return false; |
377 | } | ||
378 | |||
379 | bool BackendHelper::GetFieldDesc(const soc_reg_t& reg_desc, const QString& field, | ||
380 | soc_reg_field_t& field_desc) | ||
381 | { | ||
382 | for(size_t i = 0; i < reg_desc.field.size(); i++) | ||
383 | if(reg_desc.field[i].name.c_str() == field) | ||
384 | field_desc = reg_desc.field[i]; | ||
385 | return false; | ||
386 | } | ||
387 | |||
388 | bool BackendHelper::GetRegisterAddress(const QString& dev, const QString& reg, | ||
389 | soc_addr_t& addr) | ||
390 | { | ||
391 | size_t dev_index, reg_index; | ||
392 | soc_dev_t dev_desc; | ||
393 | soc_reg_t reg_desc; | ||
394 | if(!GetDeviceDesc(dev, dev_desc, dev_index)) | ||
395 | return false; | ||
396 | if(!GetRegisterDesc(dev_desc, reg, reg_desc, reg_index)) | ||
397 | return false; | ||
398 | addr = dev_desc.addr[dev_index].addr + reg_desc.addr[reg_index].addr; | ||
399 | return true; | ||
400 | } | ||
401 | |||
402 | bool BackendHelper::ReadRegisterField(const QString& dev, const QString& reg, | ||
403 | const QString& field, soc_word_t& v) | ||
404 | { | ||
405 | size_t dev_index, reg_index; | ||
406 | soc_dev_t dev_desc; | ||
407 | soc_reg_t reg_desc; | ||
408 | soc_reg_field_t field_desc; | ||
409 | if(!GetDeviceDesc(dev, dev_desc, dev_index)) | ||
410 | return false; | ||
411 | if(!GetRegisterDesc(dev_desc, reg, reg_desc, reg_index)) | ||
145 | return false; | 412 | return false; |
146 | soc_reg_field_t *sfield = 0; | 413 | if(!GetFieldDesc(reg_desc, field, field_desc)) |
147 | for(size_t i = 0; i < sreg->field.size(); i++) | ||
148 | if(sreg->field[i].name.c_str() == field) | ||
149 | sfield = &sreg->field[i]; | ||
150 | if(sfield == 0) | ||
151 | return false; | 414 | return false; |
152 | if(!ReadRegister(dev, reg, v)) | 415 | if(!ReadRegister(dev, reg, v)) |
153 | return false; | 416 | return false; |
154 | v = (v & sfield->bitmask()) >> sfield->first_bit; | 417 | v = (v & field_desc.bitmask()) >> field_desc.first_bit; |
155 | return true; | 418 | return true; |
156 | } \ No newline at end of file | 419 | } \ No newline at end of file |
diff --git a/utils/regtools/qeditor/backend.h b/utils/regtools/qeditor/backend.h index 536eb8cec5..55f31cce52 100644 --- a/utils/regtools/qeditor/backend.h +++ b/utils/regtools/qeditor/backend.h | |||
@@ -4,16 +4,29 @@ | |||
4 | #include <QObject> | 4 | #include <QObject> |
5 | #include <QStringList> | 5 | #include <QStringList> |
6 | #include <QMap> | 6 | #include <QMap> |
7 | #include <QVector> | ||
7 | #include "soc_desc.hpp" | 8 | #include "soc_desc.hpp" |
9 | #ifdef HAVE_HWSTUB | ||
10 | #include "hwstub.h" | ||
11 | #endif | ||
8 | 12 | ||
9 | class IoBackend : public QObject | 13 | class IoBackend : public QObject |
10 | { | 14 | { |
11 | Q_OBJECT | 15 | Q_OBJECT |
12 | public: | 16 | public: |
13 | IoBackend(); | 17 | IoBackend() {} |
18 | virtual ~IoBackend() {} | ||
14 | 19 | ||
20 | enum AccessType | ||
21 | { | ||
22 | ByName, | ||
23 | ByAddress, | ||
24 | }; | ||
25 | |||
26 | virtual bool SupportAccess(AccessType type) = 0; | ||
15 | virtual QString GetSocName() = 0; | 27 | virtual QString GetSocName() = 0; |
16 | virtual bool ReadRegister(const QString& name, soc_word_t& value) = 0; | 28 | virtual bool ReadRegister(const QString& name, soc_word_t& value) = 0; |
29 | virtual bool ReadRegister(soc_addr_t addr, soc_word_t& value) = 0; | ||
17 | virtual bool Reload() = 0; | 30 | virtual bool Reload() = 0; |
18 | }; | 31 | }; |
19 | 32 | ||
@@ -21,11 +34,15 @@ class DummyIoBackend : public IoBackend | |||
21 | { | 34 | { |
22 | Q_OBJECT | 35 | Q_OBJECT |
23 | public: | 36 | public: |
24 | DummyIoBackend(); | 37 | DummyIoBackend() {} |
25 | 38 | ||
26 | virtual QString GetSocName(); | 39 | virtual bool SupportAccess(AccessType type) { (void) type; return false; } |
27 | virtual bool ReadRegister(const QString& name, soc_word_t& value); | 40 | virtual QString GetSocName() { return ""; } |
28 | virtual bool Reload(); | 41 | virtual bool ReadRegister(const QString& name, soc_word_t& value) |
42 | { (void) name; (void) value; return false; } | ||
43 | virtual bool ReadRegister(soc_addr_t addr, soc_word_t& value) | ||
44 | { (void) addr; (void) value; return false; } | ||
45 | virtual bool Reload() { return false; } | ||
29 | }; | 46 | }; |
30 | 47 | ||
31 | class FileIoBackend : public IoBackend | 48 | class FileIoBackend : public IoBackend |
@@ -34,8 +51,11 @@ class FileIoBackend : public IoBackend | |||
34 | public: | 51 | public: |
35 | FileIoBackend(const QString& filename); | 52 | FileIoBackend(const QString& filename); |
36 | 53 | ||
54 | virtual bool SupportAccess(AccessType type) { return type == ByName; } | ||
37 | virtual QString GetSocName(); | 55 | virtual QString GetSocName(); |
38 | virtual bool ReadRegister(const QString& name, soc_word_t& value); | 56 | virtual bool ReadRegister(const QString& name, soc_word_t& value); |
57 | virtual bool ReadRegister(soc_addr_t addr, soc_word_t& value) | ||
58 | { (void) addr; (void) value; return false; } | ||
39 | virtual bool Reload(); | 59 | virtual bool Reload(); |
40 | 60 | ||
41 | protected: | 61 | protected: |
@@ -44,6 +64,82 @@ protected: | |||
44 | QMap< QString, soc_word_t > m_map; | 64 | QMap< QString, soc_word_t > m_map; |
45 | }; | 65 | }; |
46 | 66 | ||
67 | #ifdef HAVE_HWSTUB | ||
68 | class HWStubDevice | ||
69 | { | ||
70 | public: | ||
71 | HWStubDevice(struct libusb_device *dev); | ||
72 | ~HWStubDevice(); | ||
73 | bool IsValid(); | ||
74 | bool Open(); | ||
75 | void Close(); | ||
76 | int GetBusNumber(); | ||
77 | int GetDevAddress(); | ||
78 | /* Calls below are cached and do not require the device to be opened */ | ||
79 | inline struct hwstub_version_desc_t GetVersionInfo() { return m_hwdev_ver; } | ||
80 | inline struct hwstub_target_desc_t GetTargetInfo() { return m_hwdev_target; } | ||
81 | inline struct hwstub_stmp_desc_t GetSTMPInfo() { return m_hwdev_stmp; } | ||
82 | /* Calls below require the device to be opened */ | ||
83 | bool ReadMem(soc_addr_t addr, size_t length, void *buffer); | ||
84 | |||
85 | protected: | ||
86 | bool Probe(); | ||
87 | |||
88 | bool m_valid; | ||
89 | struct libusb_device *m_dev; | ||
90 | libusb_device_handle *m_handle; | ||
91 | struct hwstub_device_t *m_hwdev; | ||
92 | struct hwstub_version_desc_t m_hwdev_ver; | ||
93 | struct hwstub_target_desc_t m_hwdev_target; | ||
94 | struct hwstub_stmp_desc_t m_hwdev_stmp; | ||
95 | }; | ||
96 | |||
97 | class HWStubIoBackend : public IoBackend | ||
98 | { | ||
99 | Q_OBJECT | ||
100 | public: | ||
101 | HWStubIoBackend(HWStubDevice *dev); | ||
102 | virtual ~HWStubIoBackend(); | ||
103 | |||
104 | virtual bool SupportAccess(AccessType type) { return type == ByAddress; } | ||
105 | virtual QString GetSocName(); | ||
106 | virtual bool ReadRegister(const QString& name, soc_word_t& value) | ||
107 | { (void) name; (void) value; return false; } | ||
108 | virtual bool ReadRegister(soc_addr_t addr, soc_word_t& value); | ||
109 | virtual bool Reload(); | ||
110 | |||
111 | protected: | ||
112 | QString m_soc; | ||
113 | HWStubDevice *m_dev; | ||
114 | }; | ||
115 | |||
116 | #if LIBUSB_API_VERSION < 0x01000102 | ||
117 | #define LIBUSB_NO_HOTPLUG | ||
118 | #endif | ||
119 | |||
120 | class HWStubBackendHelper : public QObject | ||
121 | { | ||
122 | Q_OBJECT | ||
123 | public: | ||
124 | HWStubBackendHelper(); | ||
125 | ~HWStubBackendHelper(); | ||
126 | bool HasHotPlugSupport(); | ||
127 | QList< HWStubDevice* > GetDevList(); | ||
128 | |||
129 | signals: | ||
130 | void OnDevListChanged(bool arrived, struct libusb_device *dev); | ||
131 | |||
132 | protected: | ||
133 | #ifndef LIBUSB_NO_HOTPLUG | ||
134 | void OnHotPlug(bool arrived, struct libusb_device *dev); | ||
135 | static int HotPlugCallback(struct libusb_context *ctx, struct libusb_device *dev, | ||
136 | libusb_hotplug_event event, void *user_data); | ||
137 | libusb_hotplug_callback_handle m_hotplug_handle; | ||
138 | #endif | ||
139 | bool m_hotplug; | ||
140 | }; | ||
141 | #endif | ||
142 | |||
47 | class Backend : public QObject | 143 | class Backend : public QObject |
48 | { | 144 | { |
49 | Q_OBJECT | 145 | Q_OBJECT |
@@ -55,6 +151,9 @@ public: | |||
55 | bool GetSocByName(const QString& name, soc_t& s); | 151 | bool GetSocByName(const QString& name, soc_t& s); |
56 | IoBackend *CreateDummyIoBackend(); | 152 | IoBackend *CreateDummyIoBackend(); |
57 | IoBackend *CreateFileIoBackend(const QString& filename); | 153 | IoBackend *CreateFileIoBackend(const QString& filename); |
154 | #ifdef HAVE_HWSTUB | ||
155 | IoBackend *CreateHWStubIoBackend(HWStubDevice *dev); | ||
156 | #endif | ||
58 | 157 | ||
59 | signals: | 158 | signals: |
60 | void OnSocListChanged(); | 159 | void OnSocListChanged(); |
@@ -69,6 +168,10 @@ public: | |||
69 | bool ReadRegister(const QString& dev, const QString& reg, soc_word_t& v); | 168 | bool ReadRegister(const QString& dev, const QString& reg, soc_word_t& v); |
70 | bool ReadRegisterField(const QString& dev, const QString& reg, | 169 | bool ReadRegisterField(const QString& dev, const QString& reg, |
71 | const QString& field, soc_word_t& v); | 170 | const QString& field, soc_word_t& v); |
171 | bool GetDeviceDesc(const QString& dev, soc_dev_t& dev_desc, size_t& index); | ||
172 | bool GetRegisterDesc(const soc_dev_t& dev, const QString& reg, soc_reg_t& reg_desc, size_t& index); | ||
173 | bool GetFieldDesc(const soc_reg_t& reg_desc, const QString& field, soc_reg_field_t& field_desc); | ||
174 | bool GetRegisterAddress(const QString& dev, const QString& reg, soc_addr_t& addr); | ||
72 | private: | 175 | private: |
73 | IoBackend *m_io_backend; | 176 | IoBackend *m_io_backend; |
74 | soc_t m_soc; | 177 | soc_t m_soc; |
diff --git a/utils/regtools/qeditor/main.cpp b/utils/regtools/qeditor/main.cpp index 0e4e67bfb7..576d3a16fc 100644 --- a/utils/regtools/qeditor/main.cpp +++ b/utils/regtools/qeditor/main.cpp | |||
@@ -6,25 +6,24 @@ int main(int argc, char *argv[]) | |||
6 | { | 6 | { |
7 | QApplication app(argc, argv); | 7 | QApplication app(argc, argv); |
8 | 8 | ||
9 | Backend *backend = new Backend; | 9 | Backend backend;; |
10 | QDir dir(QCoreApplication::applicationDirPath()); | 10 | QDir dir(QCoreApplication::applicationDirPath()); |
11 | dir.cdUp(); | 11 | dir.cdUp(); |
12 | dir.cd("desc"); | 12 | dir.cd("desc"); |
13 | dir.setFilter(QDir::Files); | 13 | dir.setFilter(QDir::Files); |
14 | printf("%s\n", dir.absolutePath().toStdString().c_str()); | ||
15 | QFileInfoList list = dir.entryInfoList(); | 14 | QFileInfoList list = dir.entryInfoList(); |
16 | for(int i = 0; i < list.size(); i++) | 15 | for(int i = 0; i < list.size(); i++) |
17 | { | 16 | { |
18 | QFileInfo fileInfo = list.at(i); | 17 | QFileInfo fileInfo = list.at(i); |
19 | if(fileInfo.fileName().right(4) != ".xml" || fileInfo.fileName().left(5) != "regs-") | 18 | if(fileInfo.fileName().right(4) != ".xml" || fileInfo.fileName().left(5) != "regs-") |
20 | continue; | 19 | continue; |
21 | backend->LoadSocDesc(fileInfo.absoluteFilePath()); | 20 | backend.LoadSocDesc(fileInfo.absoluteFilePath()); |
22 | } | 21 | } |
23 | 22 | ||
24 | QCoreApplication::setOrganizationName("Rockbox"); | 23 | QCoreApplication::setOrganizationName("Rockbox"); |
25 | QCoreApplication::setApplicationName("Register Editor"); | 24 | QCoreApplication::setApplicationName("Register Editor"); |
26 | QCoreApplication::setOrganizationDomain("rockbox.org"); | 25 | QCoreApplication::setOrganizationDomain("rockbox.org"); |
27 | MainWindow win(backend); | 26 | MainWindow win(&backend); |
28 | win.show(); | 27 | win.show(); |
29 | return app.exec(); | 28 | return app.exec(); |
30 | } | 29 | } |
diff --git a/utils/regtools/qeditor/qeditor.pro b/utils/regtools/qeditor/qeditor.pro index 4e25a48d89..5604fe9d41 100644 --- a/utils/regtools/qeditor/qeditor.pro +++ b/utils/regtools/qeditor/qeditor.pro | |||
@@ -3,6 +3,16 @@ QT += widgets | |||
3 | HEADERS += mainwindow.h backend.h regtab.h analyser.h settings.h std_analysers.h | 3 | HEADERS += mainwindow.h backend.h regtab.h analyser.h settings.h std_analysers.h |
4 | SOURCES += main.cpp mainwindow.cpp regtab.cpp backend.cpp analyser.cpp std_analysers.cpp settings.cpp | 4 | SOURCES += main.cpp mainwindow.cpp regtab.cpp backend.cpp analyser.cpp std_analysers.cpp settings.cpp |
5 | LIBS += -L../lib/ -lsocdesc -lxml2 | 5 | LIBS += -L../lib/ -lsocdesc -lxml2 |
6 | INCLUDEPATH += ../lib/ | 6 | INCLUDEPATH += ../lib/ ../../hwstub/lib |
7 | 7 | ||
8 | CONFIG += debug \ No newline at end of file | 8 | unix { |
9 | !nohwstub { | ||
10 | message("Use 'qmake -config nohwstub' if you want to disable hwstub support") | ||
11 | LIBS += -L../../hwstub/lib -lhwstub | ||
12 | DEFINES += HAVE_HWSTUB | ||
13 | CONFIG += link_pkgconfig | ||
14 | PKGCONFIG += libusb-1.0 | ||
15 | } | ||
16 | } | ||
17 | |||
18 | CONFIG += debug | ||
diff --git a/utils/regtools/qeditor/regtab.cpp b/utils/regtools/qeditor/regtab.cpp index 4f7a73cffc..8f64bbf48a 100644 --- a/utils/regtools/qeditor/regtab.cpp +++ b/utils/regtools/qeditor/regtab.cpp | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <QTableWidget> | 13 | #include <QTableWidget> |
14 | #include <QHeaderView> | 14 | #include <QHeaderView> |
15 | #include <QFileDialog> | 15 | #include <QFileDialog> |
16 | #include <QDebug> | ||
16 | #include "backend.h" | 17 | #include "backend.h" |
17 | #include "analyser.h" | 18 | #include "analyser.h" |
18 | 19 | ||
@@ -65,6 +66,9 @@ RegTab::RegTab(Backend *backend, QTabWidget *parent) | |||
65 | m_data_selector = new QComboBox; | 66 | m_data_selector = new QComboBox; |
66 | m_data_selector->addItem(QIcon::fromTheme("face-sad"), "None", QVariant(DataSelNothing)); | 67 | m_data_selector->addItem(QIcon::fromTheme("face-sad"), "None", QVariant(DataSelNothing)); |
67 | m_data_selector->addItem(QIcon::fromTheme("document-open"), "File...", QVariant(DataSelFile)); | 68 | m_data_selector->addItem(QIcon::fromTheme("document-open"), "File...", QVariant(DataSelFile)); |
69 | #ifdef HAVE_HWSTUB | ||
70 | m_data_selector->addItem(QIcon::fromTheme("multimedia-player"), "Device...", QVariant(DataSelDevice)); | ||
71 | #endif | ||
68 | m_data_sel_edit = new QLineEdit; | 72 | m_data_sel_edit = new QLineEdit; |
69 | m_data_sel_edit->setReadOnly(true); | 73 | m_data_sel_edit->setReadOnly(true); |
70 | m_data_soc_label = new QLabel; | 74 | m_data_soc_label = new QLabel; |
@@ -72,6 +76,10 @@ RegTab::RegTab(Backend *backend, QTabWidget *parent) | |||
72 | data_sel_reload->setIcon(QIcon::fromTheme("view-refresh")); | 76 | data_sel_reload->setIcon(QIcon::fromTheme("view-refresh")); |
73 | data_sel_layout->addWidget(m_data_selector); | 77 | data_sel_layout->addWidget(m_data_selector); |
74 | data_sel_layout->addWidget(m_data_sel_edit); | 78 | data_sel_layout->addWidget(m_data_sel_edit); |
79 | #ifdef HAVE_HWSTUB | ||
80 | m_dev_selector = new QComboBox; | ||
81 | data_sel_layout->addWidget(m_dev_selector, 1); | ||
82 | #endif | ||
75 | data_sel_layout->addWidget(m_data_soc_label); | 83 | data_sel_layout->addWidget(m_data_soc_label); |
76 | data_sel_layout->addWidget(data_sel_reload); | 84 | data_sel_layout->addWidget(data_sel_reload); |
77 | data_sel_group->setLayout(data_sel_layout); | 85 | data_sel_group->setLayout(data_sel_layout); |
@@ -107,6 +115,10 @@ RegTab::RegTab(Backend *backend, QTabWidget *parent) | |||
107 | this, SLOT(OnAnalyserChanged(QListWidgetItem *, QListWidgetItem *))); | 115 | this, SLOT(OnAnalyserChanged(QListWidgetItem *, QListWidgetItem *))); |
108 | connect(m_analysers_list, SIGNAL(itemClicked(QListWidgetItem *)), this, | 116 | connect(m_analysers_list, SIGNAL(itemClicked(QListWidgetItem *)), this, |
109 | SLOT(OnAnalyserClicked(QListWidgetItem *))); | 117 | SLOT(OnAnalyserClicked(QListWidgetItem *))); |
118 | #ifdef HAVE_HWSTUB | ||
119 | connect(m_dev_selector, SIGNAL(currentIndexChanged(int)), | ||
120 | this, SLOT(OnDevChanged(int))); | ||
121 | #endif | ||
110 | 122 | ||
111 | OnSocListChanged(); | 123 | OnSocListChanged(); |
112 | OnDataSelChanged(DataSelNothing); | 124 | OnDataSelChanged(DataSelNothing); |
@@ -141,6 +153,10 @@ void RegTab::OnDataSelChanged(int index) | |||
141 | QVariant var = m_data_selector->itemData(index); | 153 | QVariant var = m_data_selector->itemData(index); |
142 | if(var == DataSelFile) | 154 | if(var == DataSelFile) |
143 | { | 155 | { |
156 | m_data_sel_edit->show(); | ||
157 | #ifdef HAVE_HWSTUB | ||
158 | m_dev_selector->hide(); | ||
159 | #endif | ||
144 | QFileDialog *fd = new QFileDialog(m_data_selector); | 160 | QFileDialog *fd = new QFileDialog(m_data_selector); |
145 | fd->setFilter("Textual files (*.txt);;All files (*)"); | 161 | fd->setFilter("Textual files (*.txt);;All files (*)"); |
146 | fd->setDirectory(Settings::Get()->value("regtab/loaddatadir", QDir::currentPath()).toString()); | 162 | fd->setDirectory(Settings::Get()->value("regtab/loaddatadir", QDir::currentPath()).toString()); |
@@ -155,8 +171,20 @@ void RegTab::OnDataSelChanged(int index) | |||
155 | } | 171 | } |
156 | Settings::Get()->setValue("regtab/loaddatadir", fd->directory().absolutePath()); | 172 | Settings::Get()->setValue("regtab/loaddatadir", fd->directory().absolutePath()); |
157 | } | 173 | } |
174 | #ifdef HAVE_HWSTUB | ||
175 | else if(var == DataSelDevice) | ||
176 | { | ||
177 | m_data_sel_edit->hide(); | ||
178 | m_dev_selector->show(); | ||
179 | OnDevListChanged(); | ||
180 | } | ||
181 | #endif | ||
158 | else | 182 | else |
159 | { | 183 | { |
184 | m_data_sel_edit->show(); | ||
185 | #ifdef HAVE_HWSTUB | ||
186 | m_dev_selector->hide(); | ||
187 | #endif | ||
160 | delete m_io_backend; | 188 | delete m_io_backend; |
161 | m_io_backend = m_backend->CreateDummyIoBackend(); | 189 | m_io_backend = m_backend->CreateDummyIoBackend(); |
162 | SetDataSocName(""); | 190 | SetDataSocName(""); |
@@ -204,7 +232,7 @@ void RegTab::OnAnalyserClicked(QListWidgetItem *current) | |||
204 | delete m_right_content; | 232 | delete m_right_content; |
205 | AnalyserFactory *ana = AnalyserFactory::GetAnalyserByName(current->text()); | 233 | AnalyserFactory *ana = AnalyserFactory::GetAnalyserByName(current->text()); |
206 | m_right_content = ana->Create(m_cur_soc, m_io_backend)->GetWidget(); | 234 | m_right_content = ana->Create(m_cur_soc, m_io_backend)->GetWidget(); |
207 | m_right_panel->addWidget(m_right_content); | 235 | m_right_panel->addWidget(m_right_content, 1); |
208 | } | 236 | } |
209 | 237 | ||
210 | void RegTab::DisplayRegister(soc_dev_t& dev, soc_dev_addr_t& dev_addr, | 238 | void RegTab::DisplayRegister(soc_dev_t& dev, soc_dev_addr_t& dev_addr, |
@@ -256,8 +284,8 @@ void RegTab::DisplayRegister(soc_dev_t& dev, soc_dev_addr_t& dev_addr, | |||
256 | top_layout->addStretch(); | 284 | top_layout->addStretch(); |
257 | 285 | ||
258 | soc_word_t value; | 286 | soc_word_t value; |
259 | bool has_value = m_io_backend->ReadRegister(QString().sprintf("HW.%s.%s", | 287 | BackendHelper helper(m_io_backend, m_cur_soc); |
260 | dev_addr.name.c_str(), reg_addr.name.c_str()), value); | 288 | bool has_value = helper.ReadRegister(dev_addr.name.c_str(), reg_addr.name.c_str(), value); |
261 | 289 | ||
262 | QHBoxLayout *raw_val_layout = 0; | 290 | QHBoxLayout *raw_val_layout = 0; |
263 | if(has_value) | 291 | if(has_value) |
@@ -348,6 +376,37 @@ void RegTab::OnSocListChanged() | |||
348 | m_soc_selector->addItem(socs[i]); | 376 | m_soc_selector->addItem(socs[i]); |
349 | } | 377 | } |
350 | 378 | ||
379 | #ifdef HAVE_HWSTUB | ||
380 | void RegTab::OnDevListChanged() | ||
381 | { | ||
382 | m_dev_selector->clear(); | ||
383 | QList< HWStubDevice* > list = m_hwstub_helper.GetDevList(); | ||
384 | foreach(HWStubDevice *dev, list) | ||
385 | { | ||
386 | QString name = QString("Bus %1 Device %2: %3").arg(dev->GetBusNumber()) | ||
387 | .arg(dev->GetDevAddress()).arg(dev->GetTargetInfo().bName); | ||
388 | m_dev_selector->addItem(QIcon::fromTheme("multimedia-player"), name, | ||
389 | QVariant::fromValue((void *)dev)); | ||
390 | } | ||
391 | if(list.size() > 0) | ||
392 | m_dev_selector->setCurrentIndex(0); | ||
393 | else | ||
394 | SetDataSocName(""); | ||
395 | } | ||
396 | |||
397 | void RegTab::OnDevChanged(int index) | ||
398 | { | ||
399 | if(index == -1) | ||
400 | return; | ||
401 | HWStubDevice *dev = reinterpret_cast< HWStubDevice* >(m_dev_selector->itemData(index).value< void* >()); | ||
402 | delete m_io_backend; | ||
403 | m_io_backend = m_backend->CreateHWStubIoBackend(dev); | ||
404 | SetDataSocName(m_io_backend->GetSocName()); | ||
405 | OnDataSocActivated(m_io_backend->GetSocName()); | ||
406 | OnDataChanged(); | ||
407 | } | ||
408 | #endif | ||
409 | |||
351 | void RegTab::FillDevSubTree(RegTreeItem *item) | 410 | void RegTab::FillDevSubTree(RegTreeItem *item) |
352 | { | 411 | { |
353 | soc_dev_t& sd = m_cur_soc.dev[item->GetDevIndex()]; | 412 | soc_dev_t& sd = m_cur_soc.dev[item->GetDevIndex()]; |
diff --git a/utils/regtools/qeditor/regtab.h b/utils/regtools/qeditor/regtab.h index 7ec8c9009f..d570eb6f90 100644 --- a/utils/regtools/qeditor/regtab.h +++ b/utils/regtools/qeditor/regtab.h | |||
@@ -25,6 +25,9 @@ enum | |||
25 | { | 25 | { |
26 | DataSelNothing, | 26 | DataSelNothing, |
27 | DataSelFile, | 27 | DataSelFile, |
28 | #ifdef HAVE_HWSTUB | ||
29 | DataSelDevice, | ||
30 | #endif | ||
28 | }; | 31 | }; |
29 | 32 | ||
30 | class RegTreeItem : public QTreeWidgetItem | 33 | class RegTreeItem : public QTreeWidgetItem |
@@ -56,6 +59,10 @@ protected: | |||
56 | soc_reg_t& reg, soc_reg_addr_t& reg_addr); | 59 | soc_reg_t& reg, soc_reg_addr_t& reg_addr); |
57 | void SetDataSocName(const QString& socname); | 60 | void SetDataSocName(const QString& socname); |
58 | QComboBox *m_soc_selector; | 61 | QComboBox *m_soc_selector; |
62 | #ifdef HAVE_HWSTUB | ||
63 | QComboBox *m_dev_selector; | ||
64 | HWStubBackendHelper m_hwstub_helper; | ||
65 | #endif | ||
59 | Backend *m_backend; | 66 | Backend *m_backend; |
60 | QTreeWidget *m_reg_tree; | 67 | QTreeWidget *m_reg_tree; |
61 | soc_t m_cur_soc; | 68 | soc_t m_cur_soc; |
@@ -71,6 +78,10 @@ protected: | |||
71 | QListWidget *m_analysers_list; | 78 | QListWidget *m_analysers_list; |
72 | 79 | ||
73 | private slots: | 80 | private slots: |
81 | #ifdef HAVE_HWSTUB | ||
82 | void OnDevListChanged(); | ||
83 | void OnDevChanged(int index); | ||
84 | #endif | ||
74 | void OnSocChanged(const QString& text); | 85 | void OnSocChanged(const QString& text); |
75 | void OnSocListChanged(); | 86 | void OnSocListChanged(); |
76 | void OnRegItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous); | 87 | void OnRegItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous); |