From a36694eb4a1905ec45593ceff2fc20d7eff7c8d8 Mon Sep 17 00:00:00 2001 From: Amaury Pouly Date: Tue, 2 Aug 2016 15:37:30 +0100 Subject: 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 --- utils/hwstub/include/hwstub_protocol.h | 7 +++++ utils/hwstub/lib/hwstub_net.cpp | 49 +++++++++++++++++++++++++++++++--- utils/hwstub/tools/hwstub_load.cpp | 46 ++++++++++++++++++++++++------- 3 files changed, 90 insertions(+), 12 deletions(-) (limited to 'utils/hwstub') diff --git a/utils/hwstub/include/hwstub_protocol.h b/utils/hwstub/include/hwstub_protocol.h index 39d2f2ebfe..f767e50571 100644 --- a/utils/hwstub/include/hwstub_protocol.h +++ b/utils/hwstub/include/hwstub_protocol.h @@ -315,4 +315,11 @@ struct hwstub_exec_req_t * 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__ */ diff --git a/utils/hwstub/lib/hwstub_net.cpp b/utils/hwstub/lib/hwstub_net.cpp index 7b62abd004..ddafea6351 100644 --- a/utils/hwstub/lib/hwstub_net.cpp +++ b/utils/hwstub/lib/hwstub_net.cpp @@ -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) { - (void) addr; - (void) flags; - return error::DUMMY; + std::shared_ptr hctx = get_device()->get_context(); + if(!hctx) + return error::NO_CONTEXT; + + context *ctx = dynamic_cast(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 @@ -1200,6 +1216,33 @@ error server::handle_cmd(client_state *state, uint32_t cmd, uint32_t args[HWSTUB debug() << "[net::srv::cmd] <-- WRITE\n"; 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 { debug() << "[net::srv::cmd] <-> unknown cmd (0x" << std::hex << cmd << ")\n"; diff --git a/utils/hwstub/tools/hwstub_load.cpp b/utils/hwstub/tools/hwstub_load.cpp index 6ca6079294..7e79b206cb 100644 --- a/utils/hwstub/tools/hwstub_load.cpp +++ b/utils/hwstub/tools/hwstub_load.cpp @@ -113,6 +113,8 @@ void usage(void) printf(" --type/-t Override file type\n"); printf(" --dev/-d Device URI (see below)\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(" raw Load a raw binary blob\n"); printf(" rockbox Load a rockbox image produced by scramble\n"); @@ -129,8 +131,9 @@ int main(int argc, char **argv) { bool quiet = false; enum image_type_t type = IT_DETECT; - const char *uri = "usb:"; bool verbose = false; + const char *uri = hwstub::uri::default_uri().full_uri().c_str(); + bool no_load = false, no_exec = false; // parse command line while(1) @@ -142,10 +145,12 @@ int main(int argc, char **argv) {"type", required_argument, 0, 't'}, {"dev", required_argument, 0, 'd'}, {"verbose", no_argument, 0, 'v'}, + {"noload", no_argument, 0, 'e'}, + {"noexec", no_argument, 0, 'l'}, {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) break; switch(c) @@ -176,6 +181,11 @@ int main(int argc, char **argv) break; case 'v': verbose = true; + case 'e': + no_load = true; + break; + case 'l': + no_exec = true; break; default: abort(); @@ -266,15 +276,33 @@ int main(int argc, char **argv) return 1; } - size_t out_size = size; - ret = hwdev->write(addr, buffer, out_size, false); - if(ret != hwstub::error::SUCCESS || out_size != size) + /* load */ + if(!no_load) + { + size_t out_size = size; + ret = hwdev->write(addr, buffer, out_size, false); + 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; + } + } + else + printf("Skip load as requested\n"); + + /* exec */ + if(!no_exec) { - fprintf(stderr, "Image write failed: %s, %zu/%zu\n", error_string(ret).c_str(), - out_size, size); - goto Lerr; + 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; + } } - hwdev->exec(addr, HWSTUB_EXEC_JUMP); + else + printf("Skip exec as requested\n"); return 0; -- cgit v1.2.3