##// END OF EJS Templates
Removed crash on spwplugin while closing the manager thread didn't quit correctly.
Removed crash on spwplugin while closing the manager thread didn't quit correctly.

File last commit:

r70:a16dfc6c4beb default
r82:f085b545eb20 socexplorer-plugins-0.7-2 default
Show More
dsu3plugin.cpp
339 lines | 11.0 KiB | text/x-c | CppLexer
/*------------------------------------------------------------------------------
-- This file is a part of the SocExplorer Software
-- Copyright (C) 2011, Plasma Physics Laboratory - CNRS
--
-- 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 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-------------------------------------------------------------------------------*/
/*-- Author : Alexis Jeandet
-- Mail : alexis.jeandet@lpp.polytechnique.fr
----------------------------------------------------------------------------*/
#include "dsu3plugin.h"
#include <QFileDialog>
#include <QDir>
#include <socexplorerengine.h>
struct acceptedMemctrlr_str
{
int vid;
int pid;
const char* name;
};
const struct acceptedMemctrlr_str acceptedMemctrlr[]=
{
{0x04,0x0f,"MCTRL"},
{0x01,0x51,"FTSRCTRL"},
{0x20,0x01,"SRCTRLE_0WS" },
{0x20,0x02,"SRCTRLE_1WS" }
};
#define acceptedMemctrlrCnt 4
dsu3plugin::dsu3plugin(QWidget *parent):socexplorerplugin(parent,false)
{
this->UI = new dsu3pluginui();
this->setWidget((QWidget*)this->UI);
this->elfFile = new ElfFile();
connect(this->UI,SIGNAL(openFile()),this,SLOT(openFile()));
connect(this->UI,SIGNAL(flashTarget()),this,SLOT(flashTarget()));
connect(this->UI,SIGNAL(run()),this,SLOT(toggleRun()));
connect(this,SIGNAL(updateInfo(ElfFile*)),this->UI,SLOT(updateInfo(ElfFile*)));
this->running = false;
}
dsu3plugin::~dsu3plugin()
{
}
void dsu3plugin::openFile()
{
QString filename = QFileDialog::getOpenFileName(this,tr("Open elf File"), QDir::homePath(), tr("Elf Files (*)"));
if(filename!="")
{
this->openFile(filename);
}
}
void dsu3plugin::openFile(QString fileName)
{
this->elfFile->openFile(fileName);
emit this->updateInfo(this->elfFile);
}
bool dsu3plugin::configureTarget()
{
int detectedMctrlr=-1;
if(parent==NULL)
return false;
unsigned int DSUBASEADDRESS = SocExplorerEngine::self()->getEnumDeviceBaseAddress(this,0x01 , 0x004,0);
if(DSUBASEADDRESS == (unsigned int)-1)
DSUBASEADDRESS = 0x90000000;
unsigned int MCTRLBASEADDRESS =-1;
for(int i=0; i<acceptedMemctrlrCnt;i++)
{
MCTRLBASEADDRESS = SocExplorerEngine::self()->getEnumDeviceBaseAddress(this,acceptedMemctrlr[i].vid , acceptedMemctrlr[i].pid,0);
if(MCTRLBASEADDRESS != (unsigned int)-1)
{
SocExplorerEngine::message(this,QString("Found %1 @%2").arg(acceptedMemctrlr[i].name).arg(MCTRLBASEADDRESS,8,16),1);
detectedMctrlr=i;
break;
}
}
if(MCTRLBASEADDRESS == (unsigned int)-1)
{
SocExplorerEngine::message(this,"Can't any compatible memory controller",1);
return false;
}
//Force a debug break
WriteRegs(uIntlist()<<0x0000002f,(unsigned int)DSUBASEADDRESS);
WriteRegs(uIntlist()<<0x0000ffff,(unsigned int)DSUBASEADDRESS+0x20);
//Clear time tag counter
WriteRegs(uIntlist()<<0,(unsigned int)DSUBASEADDRESS+0x8);
//Clear ASR registers
WriteRegs(uIntlist()<<0<<0<<0,(unsigned int)DSUBASEADDRESS+0x400040);
WriteRegs(uIntlist()<<0x2,(unsigned int)DSUBASEADDRESS+0x400024);
WriteRegs(uIntlist()<<0<<0<<0<<0<<0<<0<<0<<0,(unsigned int)DSUBASEADDRESS+0x400060);
WriteRegs(uIntlist()<<0,(unsigned int)DSUBASEADDRESS+0x48);
WriteRegs(uIntlist()<<0,(unsigned int)DSUBASEADDRESS+0x000004C);
WriteRegs(uIntlist()<<0,(unsigned int)DSUBASEADDRESS+0x400040);
// {0x04,0x0f,"MCTRL"},
// {0x01,0x51,"FTSRCTRL"},
// {0x20,0x01,"SRCTRLE_0WS" },
// {0x20,0x02,"SRCTRLE_1WS" }
if(QString(acceptedMemctrlr[detectedMctrlr].name)=="MCTRL" || QString(acceptedMemctrlr[detectedMctrlr].name)=="FTSRCTRL" )
{
WriteRegs(uIntlist()<<0x2FF<<0xE60<<0,(unsigned int)MCTRLBASEADDRESS);
}
if(QString(acceptedMemctrlr[detectedMctrlr].name)=="SRCTRLE_0WS" || QString(acceptedMemctrlr[detectedMctrlr].name)=="SRCTRLE_1WS" )
{
//let's perform a mem Wash
unsigned int val = ReadReg(MCTRLBASEADDRESS);
val |=1<<31;
WriteRegs(uIntlist()<<val,(unsigned int)MCTRLBASEADDRESS);
usleep(1000*1000);
}
WriteRegs(uIntlist()<<0<<0<<0<<0,(unsigned int)DSUBASEADDRESS+0x400060);
WriteRegs(uIntlist()<<0x0000FFFF,(unsigned int)DSUBASEADDRESS+0x24);
memSet(DSUBASEADDRESS+0x300000,0,1567);
WriteRegs(uIntlist()<<0<<0xF30000E0<<0x00000002<<0x40000000<<0x40000000<<0x40000004<<0x1000000,(unsigned int)DSUBASEADDRESS+0x400000);
WriteRegs(uIntlist()<<0<<0<<0<<0<<0<<0<<0x403ffff0<<0<<0<<0<<0<<0<<0<<0<<0<<0<<0<<0<<0<<0<<0<<0<<0<<0,(unsigned int)DSUBASEADDRESS+0x300020);
WriteRegs(uIntlist()<<0x000002EF,(unsigned int)DSUBASEADDRESS);
//Disable interrupts
unsigned int APBIRQCTRLRBASEADD = (unsigned int)SocExplorerEngine::self()->getEnumDeviceBaseAddress(this,1,0x0d,0);
if(APBIRQCTRLRBASEADD == (unsigned int)-1)
return false;
WriteRegs(uIntlist()<<0x00000000,APBIRQCTRLRBASEADD+0x040);
WriteRegs(uIntlist()<<0xFFFE0000,APBIRQCTRLRBASEADD+0x080);
WriteRegs(uIntlist()<<0<<0,APBIRQCTRLRBASEADD);
//Set up timer
unsigned int APBTIMERBASEADD = (unsigned int)SocExplorerEngine::self()->getEnumDeviceBaseAddress(this,1,0x11,0);
if(APBTIMERBASEADD == (unsigned int)-1)
return false;
WriteRegs(uIntlist()<<0xffffffff,APBTIMERBASEADD+0x014);
WriteRegs(uIntlist()<<0x00000018,APBTIMERBASEADD+0x04);
WriteRegs(uIntlist()<<0x00000007,APBTIMERBASEADD+0x018);
return true;
}
bool dsu3plugin::cacheDisable()
{
return setCacheEnable(false);
}
bool dsu3plugin::cacheEnable()
{
return setCacheEnable(true);
}
bool dsu3plugin::cacheIsEnable()
{
if(parent==NULL)
return false;
unsigned int DSUBASEADDRESS = SocExplorerEngine::self()->getEnumDeviceBaseAddress(this,0x01 , 0x004,0);
if(DSUBASEADDRESS == (unsigned int)-1)
DSUBASEADDRESS = 0x90000000;
WriteRegs(uIntlist()<<2,DSUBASEADDRESS+0x400024);
unsigned int reg = ReadReg(DSUBASEADDRESS+0x700000);
return ((reg&0x0F)==0x0F);
}
bool dsu3plugin::setCacheEnable(bool enabled)
{
if(parent==NULL)
return false;
unsigned int DSUBASEADDRESS = SocExplorerEngine::self()->getEnumDeviceBaseAddress(this,0x01 , 0x004,0);
if(DSUBASEADDRESS == (unsigned int)-1)
DSUBASEADDRESS = 0x90000000;
WriteRegs(uIntlist()<<2,DSUBASEADDRESS+0x400024);
unsigned int reg = ReadReg(DSUBASEADDRESS+0x700000);
if(enabled)
{
WriteRegs(uIntlist()<<(0x0001000F|reg),DSUBASEADDRESS+0x700000);
//flushes cache.
WriteRegs(uIntlist()<<(0x0061000F|reg),DSUBASEADDRESS+0x700000);
}
else
{
WriteRegs(uIntlist()<<((!0x0001000F)&reg),DSUBASEADDRESS+0x700000);
WriteRegs(uIntlist()<<(0x00600000|reg),DSUBASEADDRESS+0x700000);
}
return true;
}
bool dsu3plugin::flashTarget()
{
stop();
cacheDisable();
configureTarget();
/*Write .text*/
this->writeSection(".text");
/*Write .data*/
this->writeSection(".data");
return true;
}
void dsu3plugin::run()
{
unsigned int DSUBASEADDRESS = SocExplorerEngine::self()->getEnumDeviceBaseAddress(this,0x01 , 0x004,0);
if(DSUBASEADDRESS == (unsigned int)-1)
DSUBASEADDRESS = 0x90000000;
WriteRegs(uIntlist()<<0,DSUBASEADDRESS+0x020);
this->running = true;
this->UI->setRunning(true);
}
void dsu3plugin::stop()
{
unsigned int DSUBASEADDRESS = SocExplorerEngine::self()->getEnumDeviceBaseAddress(this,0x01 , 0x004,0);
if(DSUBASEADDRESS == (unsigned int)-1)
DSUBASEADDRESS = 0x90000000;
WriteRegs(uIntlist()<<0xFFFF,DSUBASEADDRESS+0x020);
this->running = false;
this->UI->setRunning(false);
}
void dsu3plugin::toggleRun()
{
if(this->running)
this->stop();
else
this->run();
}
bool dsu3plugin::dumpSymbol(const QString &symbolName, QString file, const QString &format)
{
if(this->elfFile->isopened())
{
int symbolIndex=this->elfFile->getSymbolIndex(symbolName);
if(symbolIndex!=-1)
return this->dumpMemory(this->elfFile->getSymbolAddress(symbolIndex),this->elfFile->getSymbolSize(symbolIndex)/4,file,format);
}
return false;
}
QVariantList dsu3plugin::readSymbol(const QString &symbolName)
{
if(this->elfFile->isopened())
{
int symbolIndex=this->elfFile->getSymbolIndex(symbolName);
if(symbolIndex!=-1)
return socexplorerplugin::Read((unsigned int)this->elfFile->getSymbolAddress(symbolIndex),(unsigned int)this->elfFile->getSymbolSize(symbolIndex)/4);
}
return QVariantList();
}
void dsu3plugin::WriteRegs(uIntlist Values, unsigned int address)
{
unsigned int* buff;
buff = (unsigned int*)malloc(Values.count()*sizeof(unsigned int));
for(int i=0;i<Values.count();i++)
{
buff[i]=Values.at(i);
}
parent->Write(buff,(unsigned int)Values.count(),address);
free(buff);
}
unsigned int dsu3plugin::ReadReg(unsigned int address)
{
unsigned int buff;
parent->Read(&buff,1,address);
return buff;
}
void dsu3plugin::writeSection(int index)
{
char* buffch=NULL;
unsigned int* buff;
int size = this->elfFile->getSectionDatasz(index);
int sizeInt = size/4;
if(parent==NULL)
return;
this->elfFile->getSectionData(index,&buffch);
buff = (unsigned int*)malloc(((size/4)+1)*sizeof(unsigned int));
for(int i=0;i<sizeInt;i++)
{
buff[i] = 0x0FF & ((unsigned int)buffch[4*i]);
buff[i] = (buff[i]<<8) + (0x0FF & ((unsigned int)buffch[(4*i)+1]));
buff[i] = (buff[i]<<8) + (0x0FF & ((unsigned int)buffch[(4*i)+2]));
buff[i] = (buff[i]<<8) + (0x0FF & ((unsigned int)buffch[(4*i)+3]));
}
if(size%4)
{
buff[sizeInt]=0;
for(int i=(size%4);i>0;i--)
{
buff[sizeInt] = (buff[sizeInt]<<8) + (0x0FF & ((unsigned int)buffch[size-i]));
}
sizeInt++;
}
parent->Write(buff,(unsigned int)sizeInt,(unsigned int)this->elfFile->getSectionPaddr(index));
free(buff);
}
void dsu3plugin::writeSection(const QString &name)
{
if(elfFile->isopened())
{
writeSection(this->elfFile->getSectionIndex(name));
}
}
bool dsu3plugin::memSet(unsigned int address,int value, unsigned int count)
{
unsigned int* buffer = (unsigned int*)malloc(count*sizeof(unsigned int));
if(buffer!=NULL)
{
memset((void*)buffer,value,count*sizeof(unsigned int));
parent->Write(buffer,count,address);
free(buffer );
return true;
}
return false;
}