/**
|
/**
|
* @file
|
* @file
|
* @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved.
|
* @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved.
|
* @author Sergey Khabarov - sergeykhbr@gmail.com
|
* @author Sergey Khabarov - sergeykhbr@gmail.com
|
* @brief Elf-file loader command.
|
* @brief Elf-file loader command.
|
*/
|
*/
|
|
|
#include "iservice.h"
|
#include "iservice.h"
|
#include "cmd_loadelf.h"
|
#include "cmd_loadelf.h"
|
#include "coreservices/ielfreader.h"
|
#include "coreservices/ielfreader.h"
|
|
|
namespace debugger {
|
namespace debugger {
|
|
|
CmdLoadElf::CmdLoadElf(ITap *tap, ISocInfo *info)
|
CmdLoadElf::CmdLoadElf(ITap *tap, ISocInfo *info)
|
: ICommand ("loadelf", tap, info) {
|
: ICommand ("loadelf", tap, info) {
|
|
|
briefDescr_.make_string("Load ELF-file");
|
briefDescr_.make_string("Load ELF-file");
|
detailedDescr_.make_string(
|
detailedDescr_.make_string(
|
"Description:\n"
|
"Description:\n"
|
" Load ELF-file to SOC target memory. Optional key 'nocode'\n"
|
" Load ELF-file to SOC target memory. Optional key 'nocode'\n"
|
" allows to read debug information from the elf-file without\n"
|
" allows to read debug information from the elf-file without\n"
|
" target programming.\n"
|
" target programming.\n"
|
"Usage:\n"
|
"Usage:\n"
|
" loadelf filename [nocode]\n"
|
" loadelf filename [nocode]\n"
|
"Example:\n"
|
"Example:\n"
|
" loadelf /home/riscv/image.elf\n"
|
" loadelf /home/riscv/image.elf\n"
|
" loadelf /home/riscv/image.elf nocode\n");
|
" loadelf /home/riscv/image.elf nocode\n");
|
}
|
}
|
|
|
bool CmdLoadElf::isValid(AttributeType *args) {
|
bool CmdLoadElf::isValid(AttributeType *args) {
|
if ((*args)[0u].is_equal("loadelf")
|
if ((*args)[0u].is_equal("loadelf")
|
&& (args->size() == 2 || args->size() == 3)) {
|
&& (args->size() == 2 || args->size() == 3)) {
|
return CMD_VALID;
|
return CMD_VALID;
|
}
|
}
|
return CMD_INVALID;
|
return CMD_INVALID;
|
}
|
}
|
|
|
void CmdLoadElf::exec(AttributeType *args, AttributeType *res) {
|
void CmdLoadElf::exec(AttributeType *args, AttributeType *res) {
|
res->make_nil();
|
res->make_nil();
|
if (!isValid(args)) {
|
if (!isValid(args)) {
|
generateError(res, "Wrong argument list");
|
generateError(res, "Wrong argument list");
|
return;
|
return;
|
}
|
}
|
bool program = true;
|
bool program = true;
|
if (args->size() == 3
|
if (args->size() == 3
|
&& (*args)[2].is_string() && (*args)[2].is_equal("nocode")) {
|
&& (*args)[2].is_string() && (*args)[2].is_equal("nocode")) {
|
program = false;
|
program = false;
|
}
|
}
|
|
|
/**
|
/**
|
* @todo Elf Loader service change on elf-reader
|
* @todo Elf Loader service change on elf-reader
|
*/
|
*/
|
AttributeType lstServ;
|
AttributeType lstServ;
|
RISCV_get_services_with_iface(IFACE_ELFREADER, &lstServ);
|
RISCV_get_services_with_iface(IFACE_ELFREADER, &lstServ);
|
if (lstServ.size() == 0) {
|
if (lstServ.size() == 0) {
|
generateError(res, "Elf-service not found");
|
generateError(res, "Elf-service not found");
|
return;
|
return;
|
}
|
}
|
|
|
IService *iserv = static_cast<IService *>(lstServ[0u].to_iface());
|
IService *iserv = static_cast<IService *>(lstServ[0u].to_iface());
|
IElfReader *elf = static_cast<IElfReader *>(
|
IElfReader *elf = static_cast<IElfReader *>(
|
iserv->getInterface(IFACE_ELFREADER));
|
iserv->getInterface(IFACE_ELFREADER));
|
elf->readFile((*args)[1].to_string());
|
elf->readFile((*args)[1].to_string());
|
|
|
if (!program) {
|
if (!program) {
|
return;
|
return;
|
}
|
}
|
|
|
DsuMapType *dsu = info_->getpDsu();
|
DsuMapType *dsu = info_->getpDsu();
|
uint64_t soft_reset = 1;
|
uint64_t soft_reset = 1;
|
uint64_t addr = reinterpret_cast<uint64_t>(&dsu->ulocal.v.soft_reset);
|
uint64_t addr = reinterpret_cast<uint64_t>(&dsu->ulocal.v.soft_reset);
|
tap_->write(addr, 8, reinterpret_cast<uint8_t *>(&soft_reset));
|
tap_->write(addr, 8, reinterpret_cast<uint8_t *>(&soft_reset));
|
|
|
|
uint64_t sec_addr;
|
|
int sec_sz;
|
for (unsigned i = 0; i < elf->loadableSectionTotal(); i++) {
|
for (unsigned i = 0; i < elf->loadableSectionTotal(); i++) {
|
tap_->write(elf->sectionAddress(i),
|
sec_addr = elf->sectionAddress(i);
|
static_cast<int>(elf->sectionSize(i)),
|
sec_sz = static_cast<int>(elf->sectionSize(i));
|
elf->sectionData(i));
|
tap_->write(sec_addr, sec_sz, elf->sectionData(i));
|
}
|
}
|
|
|
soft_reset = 0;
|
soft_reset = 0;
|
tap_->write(addr, 8, reinterpret_cast<uint8_t *>(&soft_reset));
|
tap_->write(addr, 8, reinterpret_cast<uint8_t *>(&soft_reset));
|
}
|
}
|
|
|
|
|
} // namespace debugger
|
} // namespace debugger
|
|
|