You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
117 lines
4.8 KiB
117 lines
4.8 KiB
/***************************************************************************
|
|
* Copyright (C) 2007 Nicolas Hadacek <hadacek@kde.org> *
|
|
* *
|
|
* 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<Pic::Memory *>(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; i<cdata.protectedMaskNames.count(); i++) {
|
|
TQString pmName = cdata.protectedMaskNames[i];
|
|
const Pic::Config::Mask *tqmask = data.config().findMask(pmName, 0);
|
|
for (int k=tqmask->values.count()-1; k>=0; k--) {
|
|
if ( tqmask->values[k].name.isEmpty() ) continue;
|
|
if ( protection.isNoneProtectedValueName(tqmask->values[k].name) ) continue;
|
|
_memory->setConfigValue(pmName, tqmask->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").tqarg(label).tqarg(toHexLabel(c, 4)).tqarg(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 *tqmask = pdata.config().findMask(maskName);
|
|
TQString label = valueName + (tqmask ? "/" + tqmask->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<const Pic::Data &>(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 *tqmask = pdata.config().findMask(maskName);
|
|
Q_ASSERT(tqmask);
|
|
for (uint i=0; i<tqmask->values.count(); i++) {
|
|
TQString valueName = tqmask->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<TQString, Pic::Checksum::Data> &cmap = pdata.checksums();
|
|
TQMap<TQString, Pic::Checksum::Data>::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)
|