/*************************************************************************** * Copyright (C) 2007 Nicolas Hadacek * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include "checksum_check.h" #include "devices/base/device_group.h" //---------------------------------------------------------------------------- bool ChecksumCheck::skip(const Device::Data &data) const { return ( data.group().name()!="pic" ); } bool ChecksumCheck::init(const Device::Data &data) { _memory = static_cast(data.group().createMemory(data)); return true; } void ChecksumCheck::cleanup(const Device::Data &) { delete _memory; _memory = 0; } void ChecksumCheck::setProtection(const Pic::Data &data, const Pic::Checksum::Data &cdata, const TQString &maskName, const TQString &valueName) { const Pic::Protection &protection = data.config().protection(); if ( !maskName.isEmpty() && !valueName.isEmpty() ) _memory->setConfigValue(maskName, valueName); if ( !valueName.isEmpty() ) _memory->setUserIdToUnprotectedChecksum(); for (uint i=0; ivalues.count()-1; k>=0; k--) { if ( mask->values[k].name.isEmpty() ) continue; if ( protection.isNoneProtectedValueName(mask->values[k].name) ) continue; _memory->setConfigValue(pmName, mask->values[k].name); break; } } if ( !cdata.bbsize.isEmpty() ) _memory->setConfigValue(protection.bootSizeMaskName(), cdata.bbsize); } bool ChecksumCheck::checkChecksum(BitValue checksum, const TQString &label) { BitValue c = _memory->checksum(); if ( c!=checksum ) TEST_FAILED_RETURN(TQString("%1 %2/%3").arg(label).arg(toHexLabel(c, 4)).arg(toHexLabel(checksum, 4))) return true; } void ChecksumCheck::checkChecksum(const Pic::Data &pdata, const TQString &maskName, const TQString &valueName, bool &ok) { if ( !pdata.checksums().contains(valueName) ) { const Pic::Config::Mask *mask = pdata.config().findMask(maskName); TQString label = valueName + (mask ? "/" + mask->name : TQString()); printf("Missing checksum for \"%s\"", label.latin1()); return; } const Pic::Checksum::Data &cdata = pdata.checksums()[valueName]; _memory->clear(); setProtection(pdata, cdata, maskName, valueName); if ( !checkChecksum(cdata.blankChecksum, maskName + ":" + valueName + "/" + "blank") ) ok = false; _memory->checksumCheckFill(); setProtection(pdata, cdata, maskName, valueName); if ( !checkChecksum(cdata.checkChecksum, maskName + ":" + valueName + "/" + "check") ) ok = false; } bool ChecksumCheck::execute(const Device::Data &data) { const Pic::Data &pdata = static_cast(data); if ( data.name()=="18C601" || data.name()=="18C801" ) TEST_PASSED; if ( pdata.checksums().isEmpty() ) TEST_FAILED_RETURN("No checksum data"); bool ok = true; const Pic::Protection &protection = pdata.config().protection(); switch ( protection.family() ) { case Pic::Protection::NoProtection: checkChecksum(pdata, TQString(), TQString(), ok); break; case Pic::Protection::BasicProtection: { TQString maskName = protection.maskName(Pic::Protection::ProgramProtected, Pic::MemoryRangeType::Code); const Pic::Config::Mask *mask = pdata.config().findMask(maskName); Q_ASSERT(mask); for (uint i=0; ivalues.count(); i++) { TQString valueName = mask->values[i].name; if ( valueName.isEmpty() ) continue; // invalid value checkChecksum(pdata, maskName, valueName, ok); } break; } case Pic::Protection::CodeGuard: checkChecksum(pdata, "GSSEC", "Off", ok); checkChecksum(pdata, "GSSEC", "High Security", ok); break; case Pic::Protection::BlockProtection: { const TQMap &cmap = pdata.checksums(); TQMap::const_iterator it; for (it=cmap.begin(); it!=cmap.end(); ++it) checkChecksum(pdata, TQString(), it.key(), ok); break; } case Pic::Protection::Nb_Families: Q_ASSERT(false); break; } if ( !ok ) return false; TEST_PASSED return true; } //---------------------------------------------------------------------------- TEST_MAIN(ChecksumCheck)