diff options
-rw-r--r-- | utils/hwstub/include/hwstub_protocol.h | 7 | ||||
-rw-r--r-- | utils/hwstub/lib/hwstub_net.cpp | 49 | ||||
-rw-r--r-- | utils/hwstub/tools/hwstub_load.cpp | 46 |
3 files changed, 90 insertions, 12 deletions
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 | |||
315 | * Receive: no data | 315 | * Receive: no data |
316 | */ | 316 | */ |
317 | 317 | ||
318 | /** | ||
319 | * HWSERVER_EXEC: | ||
320 | * Execute code. | ||
321 | * Send: args[0] = handle ID, args[1] = addr, args[2] = flags, no data | ||
322 | * Receive: no data | ||
323 | */ | ||
324 | |||
318 | #endif /* __HWSTUB_PROTOCOL__ */ | 325 | #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) | |||
714 | 714 | ||
715 | error handle::exec_dev(uint32_t addr, uint16_t flags) | 715 | error handle::exec_dev(uint32_t addr, uint16_t flags) |
716 | { | 716 | { |
717 | (void) addr; | 717 | std::shared_ptr<hwstub::context> hctx = get_device()->get_context(); |
718 | (void) flags; | 718 | if(!hctx) |
719 | return error::DUMMY; | 719 | return error::NO_CONTEXT; |
720 | |||
721 | context *ctx = dynamic_cast<context*>(hctx.get()); | ||
722 | ctx->debug() << "[net::handle] --> EXEC(" << m_handle_id << ",0x" << std::hex | ||
723 | << addr << ", 0x" << std::hex << flags << ")\n"; | ||
724 | uint32_t args[HWSTUB_NET_ARGS] = {0}; | ||
725 | args[0] = m_handle_id; | ||
726 | args[1] = addr; | ||
727 | args[2] = flags; | ||
728 | error err = ctx->send_cmd(HWSERVER_EXEC, args, nullptr, 0, nullptr, nullptr); | ||
729 | if(err != error::SUCCESS) | ||
730 | { | ||
731 | ctx->debug() << "[net::handle] <-- EXEC failed: " << error_string(err) << "\n"; | ||
732 | return err; | ||
733 | } | ||
734 | ctx->debug() << "[net::handle] <-- EXEC\n"; | ||
735 | return error::SUCCESS; | ||
720 | } | 736 | } |
721 | 737 | ||
722 | error handle::status() const | 738 | error handle::status() const |
@@ -1200,6 +1216,33 @@ error server::handle_cmd(client_state *state, uint32_t cmd, uint32_t args[HWSTUB | |||
1200 | debug() << "[net::srv::cmd] <-- WRITE\n"; | 1216 | debug() << "[net::srv::cmd] <-- WRITE\n"; |
1201 | return error::SUCCESS; | 1217 | return error::SUCCESS; |
1202 | } | 1218 | } |
1219 | /* HWSERVER_EXEC */ | ||
1220 | else if(cmd == HWSERVER_EXEC) | ||
1221 | { | ||
1222 | uint32_t hid = args[0]; | ||
1223 | uint32_t addr = args[1]; | ||
1224 | uint32_t flags = args[2]; | ||
1225 | debug() << "[net::srv::cmd] --> EXEC(" << hid << ",0x" << std::hex << addr << "," | ||
1226 | << "0x" << std::hex << flags << ")\n"; | ||
1227 | /* check ID is valid */ | ||
1228 | auto it = state->handle_map.find(hid); | ||
1229 | if(it == state->handle_map.end()) | ||
1230 | { | ||
1231 | debug() << "[net::srv::cmd] unknown handle ID\n"; | ||
1232 | debug() << "[net::srv::cmd] <-- EXEC (error)\n"; | ||
1233 | return error::ERROR; | ||
1234 | } | ||
1235 | /* exec */ | ||
1236 | error err = it->second->exec(addr, flags); | ||
1237 | if(err != error::SUCCESS) | ||
1238 | { | ||
1239 | debug() << "[net::srv::cmd] cannot write: " << error_string(err) << "\n"; | ||
1240 | debug() << "[net::srv::cmd] <-- EXEC (error)\n"; | ||
1241 | return err; | ||
1242 | } | ||
1243 | debug() << "[net::srv::cmd] <-- EXEC\n"; | ||
1244 | return error::SUCCESS; | ||
1245 | } | ||
1203 | else | 1246 | else |
1204 | { | 1247 | { |
1205 | debug() << "[net::srv::cmd] <-> unknown cmd (0x" << std::hex << cmd << ")\n"; | 1248 | 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) | |||
113 | printf(" --type/-t <t> Override file type\n"); | 113 | printf(" --type/-t <t> Override file type\n"); |
114 | printf(" --dev/-d <uri> Device URI (see below)\n"); | 114 | printf(" --dev/-d <uri> Device URI (see below)\n"); |
115 | printf(" --verbose/-v Display debug output\n"); | 115 | printf(" --verbose/-v Display debug output\n"); |
116 | printf(" --noload Skip loading stage and only execute the given address\n"); | ||
117 | printf(" --noexec Skip execute stage and only load data the given address\n"); | ||
116 | printf("file types:\n"); | 118 | printf("file types:\n"); |
117 | printf(" raw Load a raw binary blob\n"); | 119 | printf(" raw Load a raw binary blob\n"); |
118 | printf(" rockbox Load a rockbox image produced by scramble\n"); | 120 | printf(" rockbox Load a rockbox image produced by scramble\n"); |
@@ -129,8 +131,9 @@ int main(int argc, char **argv) | |||
129 | { | 131 | { |
130 | bool quiet = false; | 132 | bool quiet = false; |
131 | enum image_type_t type = IT_DETECT; | 133 | enum image_type_t type = IT_DETECT; |
132 | const char *uri = "usb:"; | ||
133 | bool verbose = false; | 134 | bool verbose = false; |
135 | const char *uri = hwstub::uri::default_uri().full_uri().c_str(); | ||
136 | bool no_load = false, no_exec = false; | ||
134 | 137 | ||
135 | // parse command line | 138 | // parse command line |
136 | while(1) | 139 | while(1) |
@@ -142,10 +145,12 @@ int main(int argc, char **argv) | |||
142 | {"type", required_argument, 0, 't'}, | 145 | {"type", required_argument, 0, 't'}, |
143 | {"dev", required_argument, 0, 'd'}, | 146 | {"dev", required_argument, 0, 'd'}, |
144 | {"verbose", no_argument, 0, 'v'}, | 147 | {"verbose", no_argument, 0, 'v'}, |
148 | {"noload", no_argument, 0, 'e'}, | ||
149 | {"noexec", no_argument, 0, 'l'}, | ||
145 | {0, 0, 0, 0} | 150 | {0, 0, 0, 0} |
146 | }; | 151 | }; |
147 | 152 | ||
148 | int c = getopt_long(argc, argv, "?qt:d:v", long_options, NULL); | 153 | int c = getopt_long(argc, argv, "?qt:d:elv", long_options, NULL); |
149 | if(c == -1) | 154 | if(c == -1) |
150 | break; | 155 | break; |
151 | switch(c) | 156 | switch(c) |
@@ -176,6 +181,11 @@ int main(int argc, char **argv) | |||
176 | break; | 181 | break; |
177 | case 'v': | 182 | case 'v': |
178 | verbose = true; | 183 | verbose = true; |
184 | case 'e': | ||
185 | no_load = true; | ||
186 | break; | ||
187 | case 'l': | ||
188 | no_exec = true; | ||
179 | break; | 189 | break; |
180 | default: | 190 | default: |
181 | abort(); | 191 | abort(); |
@@ -266,15 +276,33 @@ int main(int argc, char **argv) | |||
266 | return 1; | 276 | return 1; |
267 | } | 277 | } |
268 | 278 | ||
269 | size_t out_size = size; | 279 | /* load */ |
270 | ret = hwdev->write(addr, buffer, out_size, false); | 280 | if(!no_load) |
271 | if(ret != hwstub::error::SUCCESS || out_size != size) | 281 | { |
282 | size_t out_size = size; | ||
283 | ret = hwdev->write(addr, buffer, out_size, false); | ||
284 | if(ret != hwstub::error::SUCCESS || out_size != size) | ||
285 | { | ||
286 | fprintf(stderr, "Image write failed: %s, %zu/%zu\n", error_string(ret).c_str(), | ||
287 | out_size, size); | ||
288 | goto Lerr; | ||
289 | } | ||
290 | } | ||
291 | else | ||
292 | printf("Skip load as requested\n"); | ||
293 | |||
294 | /* exec */ | ||
295 | if(!no_exec) | ||
272 | { | 296 | { |
273 | fprintf(stderr, "Image write failed: %s, %zu/%zu\n", error_string(ret).c_str(), | 297 | ret = hwdev->exec(addr, HWSTUB_EXEC_JUMP); |
274 | out_size, size); | 298 | if(ret != hwstub::error::SUCCESS) |
275 | goto Lerr; | 299 | { |
300 | fprintf(stderr, "Exec failed: %s\n", error_string(ret).c_str()); | ||
301 | goto Lerr; | ||
302 | } | ||
276 | } | 303 | } |
277 | hwdev->exec(addr, HWSTUB_EXEC_JUMP); | 304 | else |
305 | printf("Skip exec as requested\n"); | ||
278 | 306 | ||
279 | return 0; | 307 | return 0; |
280 | 308 | ||