diff options
Diffstat (limited to 'utils/regtools/qeditor/backend.cpp')
| -rw-r--r-- | utils/regtools/qeditor/backend.cpp | 422 |
1 files changed, 290 insertions, 132 deletions
diff --git a/utils/regtools/qeditor/backend.cpp b/utils/regtools/qeditor/backend.cpp index cbaff73..5f006b0 100644 --- a/utils/regtools/qeditor/backend.cpp +++ b/utils/regtools/qeditor/backend.cpp @@ -28,15 +28,15 @@ * SocFile */ SocFile::SocFile() - :m_valid(false) + :m_valid(true) { } SocFile::SocFile(const QString& filename) :m_filename(filename) { - m_valid = parse_xml(filename.toStdString(), m_soc); - normalize(m_soc); + soc_desc::error_context_t ctx; + m_valid = soc_desc::parse_xml(filename.toStdString(), m_soc, ctx); } bool SocFile::IsValid() @@ -44,9 +44,12 @@ bool SocFile::IsValid() return m_valid; } -SocRef SocFile::GetSocRef() +soc_desc::soc_ref_t SocFile::GetSocRef() { - return SocRef(this); + if(m_valid) + return soc_desc::soc_ref_t(&m_soc); + else + return soc_desc::soc_ref_t(); } QString SocFile::GetFilename() @@ -67,15 +70,22 @@ QList< SocFileRef > Backend::GetSocFileList() { QList< SocFileRef > list; for(std::list< SocFile >::iterator it = m_socs.begin(); it != m_socs.end(); ++it) - list.append(SocFileRef(&(*it))); + { + if(it->IsValid()) + list.append(SocFileRef(&(*it))); + } return list; } -QList< SocRef > Backend::GetSocList() +QList< soc_desc::soc_ref_t > Backend::GetSocList() { - QList< SocRef > list; + QList< soc_desc::soc_ref_t > list; for(std::list< SocFile >::iterator it = m_socs.begin(); it != m_socs.end(); ++it) - list.append(it->GetSocRef()); + { + soc_desc::soc_ref_t r = it->GetSocRef(); + if(r.valid()) + list.append(r); + } return list; } @@ -85,7 +95,7 @@ bool Backend::LoadSocDesc(const QString& filename) if(!f.IsValid()) return false; m_socs.push_back(f); - emit OnSocListChanged(); + emit OnSocAdded(SocFileRef(&m_socs.back())); return true; } @@ -107,6 +117,63 @@ IoBackend *Backend::CreateHWStubIoBackend(HWStubDevice *dev) #endif /** + * DummyIoBackend + */ + +DummyIoBackend::DummyIoBackend() +{ +} + +bool DummyIoBackend::IsValid() +{ + return false; +} + +QString DummyIoBackend::GetSocName() +{ + return ""; +} + +bool DummyIoBackend::ReadRegister(soc_addr_t addr, soc_word_t& value, + unsigned width) +{ + Q_UNUSED(addr); + Q_UNUSED(value); + Q_UNUSED(width); + return false; +} + +bool DummyIoBackend::Reload() +{ + return false; +} + +bool DummyIoBackend::IsReadOnly() +{ + return true; +} + +bool DummyIoBackend::WriteRegister(soc_addr_t addr, soc_word_t value, + unsigned width, WriteMode mode) +{ + Q_UNUSED(addr); + Q_UNUSED(value); + Q_UNUSED(mode); + Q_UNUSED(width); + return false; +} + +bool DummyIoBackend::IsDirty() +{ + return false; +} + +bool DummyIoBackend::Commit() +{ + return false; +} + +/** * RamIoBackend */ RamIoBackend::RamIoBackend(const QString& soc_name) @@ -114,9 +181,36 @@ RamIoBackend::RamIoBackend(const QString& soc_name) m_soc = soc_name; } -bool RamIoBackend::ReadRegister(const QString& name, soc_word_t& value) +bool RamIoBackend::IsValid() +{ + return m_soc != ""; +} + +QString RamIoBackend::GetSocName() +{ + return m_soc; +} + +void RamIoBackend::SetSocName(const QString& soc_name) +{ + m_soc = soc_name; +} + +bool RamIoBackend::RamIoBackend::Reload() { - QMap<QString, soc_word_t>::const_iterator it = m_map.find(name); + return false; +} + +bool RamIoBackend::IsReadOnly() +{ + return false; +} + +bool RamIoBackend::ReadRegister(soc_addr_t addr, soc_word_t& value, + unsigned width) +{ + Q_UNUSED(width); + QMap<soc_addr_t, soc_word_t>::const_iterator it = m_map.find(addr); if(it == m_map.end()) return false; value = it.value(); @@ -128,19 +222,29 @@ void RamIoBackend::DeleteAll() m_map.clear(); } -bool RamIoBackend::WriteRegister(const QString& name, soc_word_t value, WriteMode mode) +bool RamIoBackend::WriteRegister(soc_addr_t addr, soc_word_t value, + unsigned width, WriteMode mode) { + Q_UNUSED(width); switch(mode) { - case Write: m_map[name] = value; return true; - case Set: m_map[name] |= value; return true; - case Clear: m_map[name] &= ~value; return true; - case Toggle: m_map[name] ^= value; return true; + case Write: m_map[addr] = value; return true; + case Set: m_map[addr] |= value; return true; + case Clear: m_map[addr] &= ~value; return true; + case Toggle: m_map[addr] ^= value; return true; default: return false; } } +bool RamIoBackend::IsDirty() +{ + return false; +} +bool RamIoBackend::Commit() +{ + return false; +} /** * FileIoBackend @@ -154,6 +258,10 @@ FileIoBackend::FileIoBackend(const QString& filename, const QString& soc_name) Reload(); } +bool FileIoBackend::IsValid() +{ + return m_valid; +} bool FileIoBackend::Reload() { @@ -170,25 +278,27 @@ bool FileIoBackend::Reload() int idx = line.indexOf('='); if(idx == -1) continue; - QString key = line.left(idx).trimmed(); - bool ok; - soc_word_t val = line.mid(idx + 1).trimmed().toULong(&ok, 0); - if(key == "HW") - m_soc = line.mid(idx + 1).trimmed(); - else if(ok) - RamIoBackend::WriteRegister(key, val, Write); + QString key_str = line.left(idx).trimmed(); + QString val_str = line.mid(idx + 1).trimmed(); + bool key_ok,val_ok; + soc_word_t val = val_str.toULong(&val_ok, 0); + soc_word_t key = key_str.toULong(&key_ok, 0); + if(key_str == "soc") + m_soc = val_str; + else if(key_ok && val_ok) + RamIoBackend::WriteRegister(key, val, 32, Write); } - m_readonly = !QFileInfo(file).isWritable(); m_dirty = false; m_valid = true; return true; } -bool FileIoBackend::WriteRegister(const QString& name, soc_word_t value, WriteMode mode) +bool FileIoBackend::WriteRegister(soc_addr_t addr, soc_word_t value, + unsigned width, WriteMode mode) { m_dirty = true; - return RamIoBackend::WriteRegister(name, value, mode); + return RamIoBackend::WriteRegister(addr, value, width, mode); } bool FileIoBackend::Commit() @@ -199,17 +309,32 @@ bool FileIoBackend::Commit() if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) return false; QTextStream out(&file); - out << "HW = " << m_soc << "\n"; - QMapIterator< QString, soc_word_t > it(m_map); + out << "soc = " << m_soc << "\n"; + QMapIterator< soc_addr_t, soc_word_t > it(m_map); while(it.hasNext()) { it.next(); - out << it.key() << " = " << hex << showbase << it.value() << "\n"; + out << hex << showbase << it.key() << " = " << hex << showbase << it.value() << "\n"; } out.flush(); return file.flush(); } +bool FileIoBackend::IsReadOnly() +{ + return m_readonly; +} + +bool FileIoBackend::IsDirty() +{ + return m_dirty; +} + +QString FileIoBackend::GetFileName() +{ + return m_filename; +} + #ifdef HAVE_HWSTUB /** * HWStubDevice @@ -355,6 +480,8 @@ HWStubIoBackend::HWStubIoBackend(HWStubDevice *dev) else m_soc = QString("pp%1").arg(pp.wChipID, 4, 16, QChar('0')); } + else if(target.dID == HWSTUB_TARGET_ATJ) + m_soc = "atj213x"; else m_soc = target.bName; } @@ -369,13 +496,44 @@ HWStubIoBackend::~HWStubIoBackend() delete m_dev; } -bool HWStubIoBackend::ReadRegister(soc_addr_t addr, soc_word_t& value) +bool HWStubIoBackend::IsValid() +{ + return m_dev->IsValid(); +} + +bool HWStubIoBackend::IsReadOnly() +{ + return false; +} + +bool HWStubIoBackend::IsDirty() { - return m_dev->ReadMem(addr, sizeof(value), &value); + return false; } -bool HWStubIoBackend::WriteRegister(soc_addr_t addr, soc_word_t value, WriteMode mode) +bool HWStubIoBackend::Commit() { + return true; +} + +HWStubDevice *HWStubIoBackend::GetDevice() +{ + return m_dev; +} + +bool HWStubIoBackend::ReadRegister(soc_addr_t addr, soc_word_t& value, + unsigned width) +{ + if(width != 8 && width != 16 && width != 32) + return false; + return m_dev->ReadMem(addr, width / 8, &value); +} + +bool HWStubIoBackend::WriteRegister(soc_addr_t addr, soc_word_t value, + unsigned width, WriteMode mode) +{ + if(width != 8 && width != 16 && width != 32) + return false; switch(mode) { case Set: addr += 4; break; @@ -383,7 +541,7 @@ bool HWStubIoBackend::WriteRegister(soc_addr_t addr, soc_word_t value, WriteMode case Toggle: addr += 12; break; default: break; } - return m_dev->WriteMem(addr, sizeof(value), &value); + return m_dev->WriteMem(addr, width / 8, &value); } bool HWStubIoBackend::Reload() @@ -486,146 +644,146 @@ lib_usb_init __lib_usb_init; * BackendHelper */ -BackendHelper::BackendHelper(IoBackend *io_backend, const SocRef& soc) +BackendHelper::BackendHelper(IoBackend *io_backend, const soc_desc::soc_ref_t& soc) :m_io_backend(io_backend), m_soc(soc) { } -bool BackendHelper::ReadRegister(const QString& dev, const QString& reg, soc_word_t& v) +QString BackendHelper::GetPath(const soc_desc::node_inst_t& inst) { - if(m_io_backend->SupportAccess(IoBackend::ByName)) - return m_io_backend->ReadRegister("HW." + dev + "." + reg, v); - if(m_io_backend->SupportAccess(IoBackend::ByAddress)) - { - soc_addr_t addr; - if(GetRegisterAddress(dev, reg, addr)) - return m_io_backend->ReadRegister(addr, v); - } - return false; -} - -bool BackendHelper::WriteRegister(const QString& dev, const QString& reg, - soc_word_t v, IoBackend::WriteMode mode) -{ - if(m_io_backend->SupportAccess(IoBackend::ByName)) - return m_io_backend->WriteRegister("HW." + dev + "." + reg, v, mode); - if(m_io_backend->SupportAccess(IoBackend::ByAddress)) - { - soc_addr_t addr; - if(GetRegisterAddress(dev, reg, addr)) - return m_io_backend->WriteRegister(addr, v, mode); - } - return false; + if(!inst.valid() || inst.is_root()) + return QString(); + QString s = GetPath(inst.parent()); + if(!s.isEmpty()) + s += "."; + s += inst.name().c_str(); + if(inst.is_indexed()) + s = QString("%1[%2]").arg(s).arg(inst.index()); + return s; } -bool BackendHelper::GetDevRef(const QString& sdev, SocDevRef& ref) +soc_desc::node_inst_t BackendHelper::ParsePath(const QString& path) { - for(size_t i = 0; i < m_soc.GetSoc().dev.size(); i++) + soc_desc::node_inst_t inst = m_soc.root_inst(); + /* empty path is root */ + if(path.isEmpty()) + return inst; + int pos = 0; + while(pos < path.size()) { - const soc_dev_t& dev = m_soc.GetSoc().dev[i]; - for(size_t j = 0; j < dev.addr.size(); j++) - if(dev.addr[j].name.c_str() == sdev) - { - ref = SocDevRef(m_soc, i, j); - return true; - } + /* try to find the next separator */ + int next = path.indexOf('.', pos); + if(next == -1) + next = path.size(); + /* try to find the index, if any */ + int lidx = path.indexOf('[', pos); + if(lidx == -1 || lidx > next) + lidx = next; + /* extract name */ + std::string name = path.mid(pos, lidx - pos).toStdString(); + /* and index */ + if(lidx < next) + { + int ridx = path.indexOf(']', lidx + 1); + /* syntax error ? */ + if(ridx == -1 || ridx > next) + return soc_desc::node_inst_t(); + /* invalid number ? */ + bool ok = false; + size_t idx = path.mid(lidx + 1, ridx - lidx - 1).toUInt(&ok); + if(ok) + inst = inst.child(name, idx); + else + inst = soc_desc::node_inst_t(); + } + else + inst = inst.child(name); + /* advance right after the separator */ + pos = next + 1; } - return false; + return inst; } -bool BackendHelper::GetRegRef(const SocDevRef& dev, const QString& sreg, SocRegRef& ref) +bool BackendHelper::ReadRegister(const soc_desc::node_inst_t& inst, + soc_word_t& v) { - const soc_dev_t& sdev = dev.GetDev(); - for(size_t i = 0; i < sdev.reg.size(); i++) - { - const soc_reg_t& reg = sdev.reg[i]; - for(size_t j = 0; j < reg.addr.size(); j++) - { - if(reg.addr[j].name.c_str() == sreg) - { - ref = SocRegRef(dev, i, j); - return true; - } - } - } - return false; + soc_addr_t addr; + if(!GetRegisterAddress(inst, addr)) + return false; + return m_io_backend->ReadRegister(addr, v, inst.node().reg().get()->width); } -bool BackendHelper::GetFieldRef(const SocRegRef& reg, const QString& sfield, SocFieldRef& ref) +bool BackendHelper::WriteRegister(const soc_desc::node_inst_t& inst, + soc_word_t v, IoBackend::WriteMode mode) { - for(size_t i = 0; i < reg.GetReg().field.size(); i++) - if(reg.GetReg().field[i].name.c_str() == sfield) - { - ref = SocFieldRef(reg, i); - return true; - } - return false; + soc_addr_t addr; + if(!GetRegisterAddress(inst, addr)) + return false; + return m_io_backend->WriteRegister(addr, v, inst.node().reg().get()->width, mode); } -bool BackendHelper::GetRegisterAddress(const QString& dev, const QString& reg, +bool BackendHelper::GetRegisterAddress(const soc_desc::node_inst_t& inst, soc_addr_t& addr) { - SocDevRef dev_ref; - SocRegRef reg_ref; - if(!GetDevRef(dev, dev_ref) || !GetRegRef(dev_ref, reg, reg_ref)) + if(!inst.valid()) return false; - addr = dev_ref.GetDevAddr().addr + reg_ref.GetRegAddr().addr; + addr = inst.addr(); return true; } -bool BackendHelper::ReadRegisterField(const QString& dev, const QString& reg, +bool BackendHelper::ReadRegisterField(const soc_desc::node_inst_t& inst, const QString& field, soc_word_t& v) { - SocDevRef dev_ref; - SocRegRef reg_ref; - SocFieldRef field_ref; - if(!GetDevRef(dev, dev_ref) || !GetRegRef(dev_ref, reg, reg_ref) || - !GetFieldRef(reg_ref, field, field_ref)) + soc_desc::field_ref_t ref = inst.node().reg().field(field.toStdString()); + if(!ref.valid()) return false; - if(!ReadRegister(dev, reg, v)) + if(!ReadRegister(inst, v)) return false; - v = (v & field_ref.GetField().bitmask()) >> field_ref.GetField().first_bit; + v = (v & ref.get()->bitmask()) >> ref.get()->pos; return true; } bool BackendHelper::DumpAllRegisters(const QString& filename, bool ignore_errors) { - FileIoBackend b(filename, QString::fromStdString(m_soc.GetSoc().name)); + FileIoBackend b(filename, QString::fromStdString(m_soc.get()->name)); bool ret = DumpAllRegisters(&b, ignore_errors); return ret && b.Commit(); } bool BackendHelper::DumpAllRegisters(IoBackend *backend, bool ignore_errors) { - BackendHelper bh(backend, m_soc); + BackendHelper helper(backend, m_soc); + return DumpAllRegisters(&helper, m_soc.root_inst(), ignore_errors); +} + +bool BackendHelper::DumpAllRegisters(BackendHelper *bh, + const soc_desc::node_inst_t& inst, bool ignore_errors) +{ bool ret = true; - for(size_t i = 0; i < m_soc.GetSoc().dev.size(); i++) + if(inst.node().reg().valid()) + { + soc_word_t val; + if(!ReadRegister(inst, val)) + { + ret = false; + if(!ignore_errors) + return false; + } + else if(!bh->WriteRegister(inst, val)) + { + ret = false; + if(!ignore_errors) + return false; + } + } + std::vector< soc_desc::node_inst_t > list = inst.children(); + for(size_t i = 0; i < list.size(); i++) { - const soc_dev_t& dev = m_soc.GetSoc().dev[i]; - for(size_t j = 0; j < dev.addr.size(); j++) + if(!DumpAllRegisters(bh, list[i], ignore_errors)) { - QString devname = QString::fromStdString(dev.addr[j].name); - for(size_t k = 0; k < dev.reg.size(); k++) - { - const soc_reg_t& reg = dev.reg[k]; - for(size_t l = 0; l < reg.addr.size(); l++) - { - QString regname = QString::fromStdString(reg.addr[l].name); - soc_word_t val; - if(!ReadRegister(devname, regname, val)) - { - ret = false; - if(!ignore_errors) - return false; - } - else if(!bh.WriteRegister(devname, regname, val)) - { - ret = false; - if(!ignore_errors) - return false; - } - } - } + ret = false; + if(!ignore_errors) + return false; } } return ret; |