forked from len0rd/rockbox
hwstub: implement EXEC command over net
Apparently I completely forgot to implement it so using hwstub over net would just fail all EXEC commands :-s Change-Id: I0d0506cbbce9b86c9a4f19036dacc922d1e51338
This commit is contained in:
parent
56340f4cd0
commit
a36694eb4a
3 changed files with 90 additions and 12 deletions
|
@ -315,4 +315,11 @@ struct hwstub_exec_req_t
|
||||||
* Receive: no data
|
* Receive: no data
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HWSERVER_EXEC:
|
||||||
|
* Execute code.
|
||||||
|
* Send: args[0] = handle ID, args[1] = addr, args[2] = flags, no data
|
||||||
|
* Receive: no data
|
||||||
|
*/
|
||||||
|
|
||||||
#endif /* __HWSTUB_PROTOCOL__ */
|
#endif /* __HWSTUB_PROTOCOL__ */
|
||||||
|
|
|
@ -714,9 +714,25 @@ error handle::get_dev_log(void *buf, size_t& buf_sz)
|
||||||
|
|
||||||
error handle::exec_dev(uint32_t addr, uint16_t flags)
|
error handle::exec_dev(uint32_t addr, uint16_t flags)
|
||||||
{
|
{
|
||||||
(void) addr;
|
std::shared_ptr<hwstub::context> hctx = get_device()->get_context();
|
||||||
(void) flags;
|
if(!hctx)
|
||||||
return error::DUMMY;
|
return error::NO_CONTEXT;
|
||||||
|
|
||||||
|
context *ctx = dynamic_cast<context*>(hctx.get());
|
||||||
|
ctx->debug() << "[net::handle] --> EXEC(" << m_handle_id << ",0x" << std::hex
|
||||||
|
<< addr << ", 0x" << std::hex << flags << ")\n";
|
||||||
|
uint32_t args[HWSTUB_NET_ARGS] = {0};
|
||||||
|
args[0] = m_handle_id;
|
||||||
|
args[1] = addr;
|
||||||
|
args[2] = flags;
|
||||||
|
error err = ctx->send_cmd(HWSERVER_EXEC, args, nullptr, 0, nullptr, nullptr);
|
||||||
|
if(err != error::SUCCESS)
|
||||||
|
{
|
||||||
|
ctx->debug() << "[net::handle] <-- EXEC failed: " << error_string(err) << "\n";
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
ctx->debug() << "[net::handle] <-- EXEC\n";
|
||||||
|
return error::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
error handle::status() const
|
error handle::status() const
|
||||||
|
@ -1200,6 +1216,33 @@ error server::handle_cmd(client_state *state, uint32_t cmd, uint32_t args[HWSTUB
|
||||||
debug() << "[net::srv::cmd] <-- WRITE\n";
|
debug() << "[net::srv::cmd] <-- WRITE\n";
|
||||||
return error::SUCCESS;
|
return error::SUCCESS;
|
||||||
}
|
}
|
||||||
|
/* HWSERVER_EXEC */
|
||||||
|
else if(cmd == HWSERVER_EXEC)
|
||||||
|
{
|
||||||
|
uint32_t hid = args[0];
|
||||||
|
uint32_t addr = args[1];
|
||||||
|
uint32_t flags = args[2];
|
||||||
|
debug() << "[net::srv::cmd] --> EXEC(" << hid << ",0x" << std::hex << addr << ","
|
||||||
|
<< "0x" << std::hex << flags << ")\n";
|
||||||
|
/* check ID is valid */
|
||||||
|
auto it = state->handle_map.find(hid);
|
||||||
|
if(it == state->handle_map.end())
|
||||||
|
{
|
||||||
|
debug() << "[net::srv::cmd] unknown handle ID\n";
|
||||||
|
debug() << "[net::srv::cmd] <-- EXEC (error)\n";
|
||||||
|
return error::ERROR;
|
||||||
|
}
|
||||||
|
/* exec */
|
||||||
|
error err = it->second->exec(addr, flags);
|
||||||
|
if(err != error::SUCCESS)
|
||||||
|
{
|
||||||
|
debug() << "[net::srv::cmd] cannot write: " << error_string(err) << "\n";
|
||||||
|
debug() << "[net::srv::cmd] <-- EXEC (error)\n";
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
debug() << "[net::srv::cmd] <-- EXEC\n";
|
||||||
|
return error::SUCCESS;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
debug() << "[net::srv::cmd] <-> unknown cmd (0x" << std::hex << cmd << ")\n";
|
debug() << "[net::srv::cmd] <-> unknown cmd (0x" << std::hex << cmd << ")\n";
|
||||||
|
|
|
@ -113,6 +113,8 @@ void usage(void)
|
||||||
printf(" --type/-t <t> Override file type\n");
|
printf(" --type/-t <t> Override file type\n");
|
||||||
printf(" --dev/-d <uri> Device URI (see below)\n");
|
printf(" --dev/-d <uri> Device URI (see below)\n");
|
||||||
printf(" --verbose/-v Display debug output\n");
|
printf(" --verbose/-v Display debug output\n");
|
||||||
|
printf(" --noload Skip loading stage and only execute the given address\n");
|
||||||
|
printf(" --noexec Skip execute stage and only load data the given address\n");
|
||||||
printf("file types:\n");
|
printf("file types:\n");
|
||||||
printf(" raw Load a raw binary blob\n");
|
printf(" raw Load a raw binary blob\n");
|
||||||
printf(" rockbox Load a rockbox image produced by scramble\n");
|
printf(" rockbox Load a rockbox image produced by scramble\n");
|
||||||
|
@ -129,8 +131,9 @@ int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
bool quiet = false;
|
bool quiet = false;
|
||||||
enum image_type_t type = IT_DETECT;
|
enum image_type_t type = IT_DETECT;
|
||||||
const char *uri = "usb:";
|
|
||||||
bool verbose = false;
|
bool verbose = false;
|
||||||
|
const char *uri = hwstub::uri::default_uri().full_uri().c_str();
|
||||||
|
bool no_load = false, no_exec = false;
|
||||||
|
|
||||||
// parse command line
|
// parse command line
|
||||||
while(1)
|
while(1)
|
||||||
|
@ -142,10 +145,12 @@ int main(int argc, char **argv)
|
||||||
{"type", required_argument, 0, 't'},
|
{"type", required_argument, 0, 't'},
|
||||||
{"dev", required_argument, 0, 'd'},
|
{"dev", required_argument, 0, 'd'},
|
||||||
{"verbose", no_argument, 0, 'v'},
|
{"verbose", no_argument, 0, 'v'},
|
||||||
|
{"noload", no_argument, 0, 'e'},
|
||||||
|
{"noexec", no_argument, 0, 'l'},
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
int c = getopt_long(argc, argv, "?qt:d:v", long_options, NULL);
|
int c = getopt_long(argc, argv, "?qt:d:elv", long_options, NULL);
|
||||||
if(c == -1)
|
if(c == -1)
|
||||||
break;
|
break;
|
||||||
switch(c)
|
switch(c)
|
||||||
|
@ -176,6 +181,11 @@ int main(int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
verbose = true;
|
verbose = true;
|
||||||
|
case 'e':
|
||||||
|
no_load = true;
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
no_exec = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
abort();
|
abort();
|
||||||
|
@ -266,15 +276,33 @@ int main(int argc, char **argv)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t out_size = size;
|
/* load */
|
||||||
ret = hwdev->write(addr, buffer, out_size, false);
|
if(!no_load)
|
||||||
if(ret != hwstub::error::SUCCESS || out_size != size)
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Image write failed: %s, %zu/%zu\n", error_string(ret).c_str(),
|
size_t out_size = size;
|
||||||
out_size, size);
|
ret = hwdev->write(addr, buffer, out_size, false);
|
||||||
goto Lerr;
|
if(ret != hwstub::error::SUCCESS || out_size != size)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Image write failed: %s, %zu/%zu\n", error_string(ret).c_str(),
|
||||||
|
out_size, size);
|
||||||
|
goto Lerr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
hwdev->exec(addr, HWSTUB_EXEC_JUMP);
|
else
|
||||||
|
printf("Skip load as requested\n");
|
||||||
|
|
||||||
|
/* exec */
|
||||||
|
if(!no_exec)
|
||||||
|
{
|
||||||
|
ret = hwdev->exec(addr, HWSTUB_EXEC_JUMP);
|
||||||
|
if(ret != hwstub::error::SUCCESS)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Exec failed: %s\n", error_string(ret).c_str());
|
||||||
|
goto Lerr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("Skip exec as requested\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue