summaryrefslogtreecommitdiff
path: root/utils/regtools/qeditor/backend.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/regtools/qeditor/backend.cpp')
-rw-r--r--utils/regtools/qeditor/backend.cpp317
1 files changed, 290 insertions, 27 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
6Backend::Backend() 10Backend::Backend()
7{ 11{
8} 12}
@@ -43,9 +47,16 @@ IoBackend *Backend::CreateDummyIoBackend()
43 return new DummyIoBackend(); 47 return new DummyIoBackend();
44} 48}
45 49
46IoBackend::IoBackend() 50#ifdef HAVE_HWSTUB
51IoBackend *Backend::CreateHWStubIoBackend(HWStubDevice *dev)
47{ 52{
53 return new HWStubIoBackend(dev);
48} 54}
55#endif
56
57/**
58 * FileIoBackend
59 */
49 60
50FileIoBackend::FileIoBackend(const QString& filename) 61FileIoBackend::FileIoBackend(const QString& filename)
51{ 62{
@@ -91,27 +102,230 @@ bool FileIoBackend::Reload()
91 return true; 102 return true;
92} 103}
93 104
94DummyIoBackend::DummyIoBackend() 105#ifdef HAVE_HWSTUB
106/**
107 * HWStubDevice
108 */
109HWStubDevice::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
98QString DummyIoBackend::GetSocName() 118HWStubDevice::~HWStubDevice()
99{ 119{
100 return ""; 120 Close();
121 libusb_unref_device(m_dev);
101} 122}
102 123
103bool DummyIoBackend::ReadRegister(const QString& name, soc_word_t& value) 124int HWStubDevice::GetBusNumber()
104{ 125{
105 (void) name; 126 return libusb_get_bus_number(m_dev);
106 (void) value; 127}
128
129int HWStubDevice::GetDevAddress()
130{
131 return libusb_get_device_address(m_dev);
132}
133
134bool 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
110bool DummyIoBackend::Reload() 167bool 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
180void 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
190bool 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
198bool HWStubDevice::IsValid()
199{
200 return m_valid;
201}
202
203
204/**
205 * HWStubIoBackend
206 */
207
208HWStubIoBackend::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
231QString HWStubIoBackend::GetSocName()
232{
233 return m_soc;
234}
235
236HWStubIoBackend::~HWStubIoBackend()
237{
238 m_dev->Close();
239}
240
241bool HWStubIoBackend::ReadRegister(soc_addr_t addr, soc_word_t& value)
242{
243 return m_dev->ReadMem(addr, sizeof(value), &value);
244}
245
246bool HWStubIoBackend::Reload()
111{ 247{
112 return true; 248 return true;
113} 249}
114 250
251/**
252 * HWStubBackendHelper
253 */
254HWStubBackendHelper::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
271HWStubBackendHelper::~HWStubBackendHelper()
272{
273#ifndef LIBUSB_NO_HOTPLUG
274 if(m_hotplug)
275 libusb_hotplug_deregister_callback(NULL, m_hotplug_handle);
276#endif
277}
278
279QList< 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
298void HWStubBackendHelper::OnHotPlug(bool arrived, struct libusb_device *dev)
299{
300 /* signal it */
301 emit OnDevListChanged(arrived, dev);
302}
303
304int 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
318bool HWStubBackendHelper::HasHotPlugSupport()
319{
320 return m_hotplug;
321}
322
323#endif
324
325/**
326 * BackendHelper
327 */
328
115BackendHelper::BackendHelper(IoBackend *io_backend, const soc_t& soc) 329BackendHelper::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
120bool BackendHelper::ReadRegister(const QString& dev, const QString& reg, soc_word_t& v) 334bool 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
125bool BackendHelper::ReadRegisterField(const QString& dev, const QString& reg, 347
126 const QString& field, soc_word_t& v) 348bool 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++) 363bool 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
379bool 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
388bool 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
402bool 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