fix bugs, getting towards RL78/G10 glitching param test

This commit is contained in:
Triss 2022-04-25 04:14:05 +02:00
parent c4bb26ead1
commit 7b40542c20
5 changed files with 329 additions and 280 deletions

View File

@ -21,8 +21,8 @@ void cli_tool78_glitch_ocd_dump(void);
void cli_tool78_glitch_param_g10(void); void cli_tool78_glitch_param_g10(void);
void cli_tool78_glitch_ocd_g10(void); void cli_tool78_glitch_ocd_g10(void);
#define DUMP_OFFSET 0/*0xef000*/ #define DUMP_OFFSET 0xef000
#define DUMP_SIZE 1024/*65536*/ #define DUMP_SIZE 4096/*65536*/
// test with decoupling caps: length in 20..500(..1500) -> ok // test with decoupling caps: length in 20..500(..1500) -> ok
// testing on ocd lock: length: 5..35 // testing on ocd lock: length: 5..35
@ -123,23 +123,45 @@ static uint8_t exec_jmp_to_ram[] = {
}; };
static uint8_t DATA_test_dbg__paramtest[102] = { static uint8_t DATA_test_dbg__paramtest[102] = {
0x71, 0x7b, 0xfa, 0xf5, 0xf0, 0x02, 0xf5, 0x78, 0x00, 0x71, 0x6a, 0xa4, 0xcf, 0x71, 0x7b, 0xfa, 0xf5, 0xf0, 0x02, 0xf5, 0x78, 0x00, 0x71, 0x6a, 0xa4,
0x76, 0x00, 0x01, 0xce, 0x22, 0x00, 0xf5, 0x62, 0x00, 0xf5, 0x77, 0x00, 0xf5, 0xcf, 0x76, 0x00, 0x01, 0xce, 0x22, 0x00, 0xf5, 0x62, 0x00, 0xf5, 0x77,
0x79, 0x00, 0xf5, 0x75, 0x00, 0xf5, 0x7c, 0x00, 0xce, 0x02, 0x00, 0xce, 0x02, 0x00, 0xf5, 0x79, 0x00, 0xf5, 0x75, 0x00, 0xf5, 0x7c, 0x00, 0xce, 0x02,
0xff, 0x30, 0x00, 0xfa, 0x16, 0x52, 0x00, 0x53, 0xff, 0x51, 0x00, 0x81, 0x93, 0x00, 0xce, 0x02, 0xff, 0x30, 0x00, 0xfa, 0x16, 0x52, 0x00, 0x53, 0xff,
0xdf, 0xfc, 0x92, 0x61, 0xf9, 0xdf, 0xf3, 0xce, 0x02, 0x00, 0x52, 0x18, 0x53, 0x51, 0x00, 0x81, 0x93, 0xdf, 0xfc, 0x92, 0x61, 0xf9, 0xdf, 0xf3, 0xce,
0xff, 0x93, 0xdf, 0xfd, 0x92, 0xdf, 0xf8, 0x51, 0x48, 0xfc, 0xa1, 0xff, 0x0e, 0x02, 0x00, 0x52, 0x18, 0x53, 0xff, 0x93, 0xdf, 0xfd, 0x92, 0xdf, 0xf8,
0x51, 0x69, 0xfc, 0xa1, 0xff, 0x0e, 0x50, 0xaa, 0x52, 0x00, 0x92, 0x61, 0xe9, 0x51, 0x48, 0xfc, 0xa1, 0xff, 0x0e, 0x51, 0x69, 0xfc, 0xa1, 0xff, 0x0e,
0x61, 0x78, 0xfc, 0xa1, 0xff, 0x0e, 0xd2, 0xdf, 0xf4, 0xef, 0xbf 0x50, 0xaa, 0x52, 0x00, 0x92, 0x61, 0xe9, 0x61, 0x78, 0xfc, 0xa1, 0xff,
0x0e, 0xd2, 0xdf, 0xf4, 0xef, 0xbf
}; };
static uint8_t dumper_shellcode[0x26] = { static uint8_t dumper_shellcode[0x26] = {
//0xe0, 0x07, 0x26, // 0xF07E0 location, 0x26 length of packet //0xe0, 0x07, 0x26, // 0xF07E0 location, 0x26 length of packet
0x41, 0x00, 0x34, 0x00, 0x00, 0x00, 0x11, 0x89, 0xFC, 0xA1, 0xFF, 0x0E, 0xA5, 0x15, 0x44, 0x41, 0x00, 0x34, 0x00, 0x00, 0x00, 0x11, 0x89, 0xFC, 0xA1, 0xFF, 0x0E, 0xA5,
0x00, 0x00, 0xDF, 0xF3, 0xEF, 0x04, 0x55, 0x00, 0x00, 0x00, 0x8E, 0xFD, 0x81, 0x5C, 0x0F, 0x15, 0x44, 0x00, 0x00, 0xDF, 0xF3, 0xEF, 0x04, 0x55, 0x00, 0x00, 0x00, 0x8E,
0x9E, 0xFD, 0x71, 0x00, 0x90, 0x00, 0xEF, 0xE0 0xFD, 0x81, 0x5C, 0x0F, 0x9E, 0xFD, 0x71, 0x00, 0x90, 0x00, 0xEF, 0xE0
}; };
static uint8_t G1M_payload_1[] = {
0xcb, 0xf8, 0xc0, 0xfe, // movw sp, #0xfea0
0xec, 0xba, 0xff, 0x0e, // br !!0xeffba
};
static uint8_t G1M_payload_2[] = {
0xec, 0x00, 0xfe, 0x0f, // br !!ffe00
};
static uint8_t G1M_paramtest[] = {
0x71, 0x7b, 0xfa, 0x51, 0x61, 0xfc, 0xdc, 0xff, 0x0e, 0xcf, 0x77, 0x00,
0x00, 0xce, 0x00, 0x00, 0xcf, 0x30, 0x00, 0x00, 0xcf, 0x50, 0x00, 0x00,
0xcf, 0x60, 0x00, 0x7f, 0xcf, 0x20, 0xff, 0x00, 0xcf, 0xf0, 0x00, 0xe5,
0xcf, 0xf3, 0x00, 0x10, 0xce, 0x00, 0xff, 0x30, 0xe0, 0xfa, 0x16, 0x52,
0x00, 0x53, 0xff, 0x51, 0xff, 0x81, 0x93, 0xdf, 0xfc, 0x61, 0xf9, 0x92,
0xdf, 0xf3, 0xce, 0x00, 0x00, 0x52, 0x18, 0x53, 0xff, 0x93, 0xdf, 0xfd,
0x92, 0xdf, 0xf8, 0x51, 0x48, 0xfc, 0xdc, 0xff, 0x0e, 0x51, 0x69, 0xfc,
0xdc, 0xff, 0x0e, 0x50, 0xaa, 0x52, 0x00, 0x92, 0x61, 0xe9, 0x61, 0x78,
0xfc, 0xdc, 0xff, 0x0e, 0xd2, 0xdf, 0xf4, 0xef, 0xbf, 0xd7
};
void cli_tool78_glitch_dump(void) { void cli_tool78_glitch_dump(void) {
uint8_t passwd[10] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; uint8_t passwd[10] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
uint16_t ver; uint16_t ver;
@ -537,13 +559,12 @@ deinit_bad:
return; return;
} }
static uint8_t DATA_G1M_paramtest[47] = { /*static uint8_t DATA_G1M_paramtest[47] = {
0xcf, 0x77, 0x00, 0x00, 0xce, 0x00, 0x00, 0xcf, 0x30, 0x00, 0x00, 0xcf, 0x50, 0xcf, 0x77, 0x00, 0x00, 0xce, 0x00, 0x00, 0xcf, 0x30, 0x00, 0x00, 0xcf, 0x50,
0x00, 0x00, 0xcf, 0x60, 0x00, 0x7f, 0xcf, 0x20, 0xff, 0x00, 0xcf, 0xf0, 0x00, 0x00, 0x00, 0xcf, 0x60, 0x00, 0x7f, 0xcf, 0x20, 0xff, 0x00, 0xcf, 0xf0, 0x00,
0xe5, 0xcf, 0xf3, 0x00, 0x10, 0xce, 0x00, 0xff, 0x51, 0x48, 0xfc, 0xdc, 0xff, 0xe5, 0xcf, 0xf3, 0x00, 0x10, 0xce, 0x00, 0xff, 0x51, 0x48, 0xfc, 0xdc, 0xff,
0x0e, 0x51, 0x69, 0xfc, 0xdc, 0xff, 0x0e, 0xd7 0x0e, 0x51, 0x69, 0xfc, 0xdc, 0xff, 0x0e, 0xd7
}; };*/
void cli_tool78_glitch_param_g10(void) { void cli_tool78_glitch_param_g10(void) {
struct tool78_hw* hw = &tool78_hw_rl78g10_uart1; struct tool78_hw* hw = &tool78_hw_rl78g10_uart1;
@ -592,45 +613,62 @@ restart:
} }
if (first) printf("result: 0x%02x\n", st); if (first) printf("result: 0x%02x\n", st);
// TODO: upload other code! st = tool78_ocd_write(hw, 0xfed0,
// can't write too much at 0xf07e0 as 0xf0800 and up contains OCD state, sizeof(G1M_payload_1), G1M_payload_1);
// overwrite this and suddenly the OCD system resets itself
st = tool78_ocd_write(hw, 0x07e0,
sizeof(exec_jmp_to_ram), exec_jmp_to_ram);
//printf("write trampoline res 0x%02x\n", st); //printf("write trampoline res 0x%02x\n", st);
if (st != 0) { if (st != 0) {
printf("trampoline write failed: %d\n", st); printf("payload 1 write failed: %d\n", st);
goto deinit_bad; goto deinit_bad;
} }
st = tool78_ocd_write(hw, 0xf900,
sizeof(DATA_test_dbg__paramtest), DATA_test_dbg__paramtest);
//printf("write code res 0x%02x\n", st);
if (st != 0) {
printf("code write failed: %d\n", st);
goto deinit_bad;
}
st = tool78_ocd_exec(hw); st = tool78_ocd_exec(hw);
//printf("exec res 0x%02x\n", st); //printf("exec res 0x%02x\n", st);
if (st != 0) { if (st != 0) {
printf("exec failed: %d\n", st); printf("payload 1 exec failed: %d\n", st);
goto deinit_bad;
}
st = tool78_ocd_write(hw, 0xfed0,
sizeof(G1M_payload_2), G1M_payload_2);
//printf("write trampoline res 0x%02x\n", st);
if (st != 0) {
printf("payload 2 write failed: %d\n", st);
goto deinit_bad;
}
st = tool78_ocd_write(hw, 0xfe00,
sizeof(G1M_paramtest), G1M_paramtest);
//printf("write trampoline res 0x%02x\n", st);
if (st != 0) {
printf("real payload write failed: %d\n", st);
goto deinit_bad;
}
st = tool78_ocd_exec(hw);
//printf("exec res 0x%02x\n", st);
if (st != 0) {
printf("real payload exec failed: %d\n", st);
goto deinit_bad;
}
// wait for initial pong
rr = hw->recv(1, checkbuf, 120*1000);
if (rr != 1) {
printf("exec code pong: no response :/ (%d)\n", rr);
goto deinit_bad;
}
if (checkbuf[0] != 'a') {
printf("bad pong response: %02x %02x\n", checkbuf[0], checkbuf[1]);
goto deinit_bad; goto deinit_bad;
} }
// test custom tool_tx call
/*rr = tool78_hw_rl78_uart1.recv(1, checkbuf, 1000);
printf("rr=%d\n", rr);
if (rr == 1) printf("0x%02x %c\n", stuff[0], stuff[0]);*/
// wait for completion // wait for completion
rr = hw->recv(2, checkbuf, 120*1000); rr = hw->recv(2, checkbuf, 120*1000);
if (rr != 2) { if (rr != 2) {
printf("exec code: no response :/ (%d)\n", rr); printf("exec code hdr: no response :/ (%d)\n", rr);
goto deinit_bad; goto deinit_bad;
} }
if (checkbuf[0] != 'H' && checkbuf[1] != 'i') { if (checkbuf[0] != 'H' && checkbuf[1] != 'i') {
printf("bad response: %02x %02x\n", checkbuf[0], checkbuf[1]); printf("bad hdr response: %02x %02x\n", checkbuf[0], checkbuf[1]);
goto deinit_bad; goto deinit_bad;
} }
@ -650,9 +688,9 @@ restart:
first = false; first = false;
while (true) { while (true) {
glitch_arm(); //glitch_arm();
rr = hw->recv(2, checkbuf, 120*1000); rr = hw->recv(2, checkbuf, 120*1000);
glitch_disarm(); //glitch_disarm();
if (rr == 2 && (checkbuf[0] != 'H' || checkbuf[1] != 'i')) rr = 0; if (rr == 2 && (checkbuf[0] != 'H' || checkbuf[1] != 'i')) rr = 0;
if (rr == 2) { if (rr == 2) {
rr = hw->recv(256, checkbuf, 120*1000); rr = hw->recv(256, checkbuf, 120*1000);
@ -682,12 +720,13 @@ restart:
} }
} }
} }
deinit_bad: deinit_bad:
busy_wait_ms(1000);
hw->deinit(); hw->deinit();
return; return;
do_reset_stuff: do_reset_stuff:
busy_wait_ms(1000);
hw->deinit(); hw->deinit();
// glitch for way too long to power cycle // glitch for way too long to power cycle
@ -699,157 +738,157 @@ do_reset_stuff:
} }
void cli_tool78_glitch_ocd_g10(void) { void cli_tool78_glitch_ocd_g10(void) {
struct tool78_hw* hw = &tool78_hw_rl78g10_uart1; // struct tool78_hw* hw = &tool78_hw_rl78g10_uart1;
//
zap_dac_set_enable(zap_dac_a | zap_dac_b); // zap_dac_set_enable(zap_dac_a | zap_dac_b);
#if 1 /* MCP48x2 */ //#if 1 /* MCP48x2 */
zap_dac_set_mulx2(zap_dac_a | zap_dac_b); // zap_dac_set_mulx2(zap_dac_a | zap_dac_b);
#else //#else
zap_dac_set_mulx2(0); // zap_dac_set_mulx2(0);
zap_dac_set_shutdown(false); // zap_dac_set_shutdown(false);
#endif //#endif
//
zap_max_use_vhi_jp300(true); // zap_max_use_vhi_jp300(true);
zap_max_set_inhibit(false); // zap_max_set_inhibit(false);
//
if (!glitch_init_core1_stuff(false, ZAP_GLITCH_OUT)) { // if (!glitch_init_core1_stuff(false, ZAP_GLITCH_OUT)) {
printf("bad glitcher params!\n"); // printf("bad glitcher params!\n");
return; // return;
} // }
//
gpio_set_function(2, GPIO_FUNC_SIO); // gpio_set_function(2, GPIO_FUNC_SIO);
gpio_set_dir(2, GPIO_OUT); // gpio_set_dir(2, GPIO_OUT);
gpio_put(2, false); // gpio_put(2, false);
//
//gpio_set_function(3, GPIO_FUNC_SIO); // //gpio_set_function(3, GPIO_FUNC_SIO);
//gpio_set_dir(3, GPIO_OUT); // //gpio_set_dir(3, GPIO_OUT);
//gpio_put(3, false); // //gpio_put(3, false);
//
uint8_t passwd[10] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; // uint8_t passwd[10] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
int st, rr/*, r0, r1, r2*/; // int st, rr/*, r0, r1, r2*/;
static uint8_t checkbuf[256]; // static uint8_t checkbuf[256];
bool first = true; // bool first = true;
//
restart: //restart:
//trl78_uart1_set_exclusive(true); // //trl78_uart1_set_exclusive(true);
//hw->rx_set_stop_bit(false); // //hw->rx_set_stop_bit(false);
gpio_put(2, false); // gpio_put(2, false);
/*glitch_disarm(); // /*glitch_disarm();
busy_wait_ms(40);*/ // busy_wait_ms(40);*/
//
st = tool78_init_ocd(hw, NULL, passwd); // st = tool78_init_ocd(hw, NULL, passwd);
if (st == 0xc3) { // if (st == 0xc3) {
printf("aa\n"); // printf("aa\n");
st = 0; // st = 0;
rr = hw->recv(1, (uint8_t*)&st, 120*1000); // rr = hw->recv(1, (uint8_t*)&st, 120*1000);
printf("rr=%d\n", rr); // printf("rr=%d\n", rr);
if (rr != 1) { // if (rr != 1) {
printf("aaaa\n"); // printf("aaaa\n");
goto do_reset_stuff; // goto do_reset_stuff;
} // }
} // }
if (first) printf("result: 0x%02x\n", st); // if (first) printf("result: 0x%02x\n", st);
if (st == 0xc1) goto do_reset_stuff; // if (st == 0xc1) goto do_reset_stuff;
if (st != tool78_stat_no_ocd_status) { // if (st != tool78_stat_no_ocd_status) {
printf("init: expected status timeout error, got %d\n", st); // printf("init: expected status timeout error, got %d\n", st);
goto deinit_bad; // goto deinit_bad;
} // }
busy_wait_ms(16); // leave time to recharge // busy_wait_ms(16); // leave time to recharge
//
// TODO: update description // // TODO: update description
// right now, the RL78 core is stuck in an infinite loop doing nothing in // // right now, the RL78 core is stuck in an infinite loop doing nothing in
// the debug monitor part of its bootrom. however, the code we need is // // the debug monitor part of its bootrom. however, the code we need is
// right below it, so we can simply try to glitch it without having to meet // // right below it, so we can simply try to glitch it without having to meet
// the timing // // the timing
// see https://fail0verflow.com/blog/2018/ps4-syscon/ for more info // // see https://fail0verflow.com/blog/2018/ps4-syscon/ for more info
//
// try up to 16 times because we can't discern between a reset and a glitch // // try up to 16 times because we can't discern between a reset and a glitch
// that had no effect. after 16 iterations without result, reset the RL78 // // that had no effect. after 16 iterations without result, reset the RL78
// and try again. // // and try again.
// a successful glitch will output a single null byte over the TOOL0 line // // a successful glitch will output a single null byte over the TOOL0 line
//
// apparently we have about 95 ms until the infinite loop gets reset into // // apparently we have about 95 ms until the infinite loop gets reset into
// the MCU flash automatically? somehow?? I suppose it's the WDT // // the MCU flash automatically? somehow?? I suppose it's the WDT
if (first) printf("all set, let's go\n"); // if (first) printf("all set, let's go\n");
first = false; // first = false;
//
//hw->rx_set_stop_bit(false); // //hw->rx_set_stop_bit(false);
glitch_arm(); // glitch_arm();
for (size_t i = 0; i < 16; ++i) { // for (size_t i = 0; i < 16; ++i) {
zap_dac_set_b(zap_adc_read(1)); // zap_dac_set_b(zap_adc_read(1));
zap_dac_latch(); // zap_dac_latch();
//glitch_trigger_sw_core1(); // //glitch_trigger_sw_core1();
glitch_trigger_sw_pio(); // glitch_trigger_sw_pio();
rr = hw->recv(1, checkbuf, 12*1000); // rr = hw->recv(1, checkbuf, 12*1000);
if (rr != 1 || checkbuf[0] == 0xff) { // if (rr != 1 || checkbuf[0] == 0xff) {
busy_wait_ms(1); // leave time to recharge // busy_wait_ms(1); // leave time to recharge
printf("."); // printf(".");
continue; // continue;
} // }
//
printf("checkbuf: %d", checkbuf[0]); // printf("checkbuf: %d", checkbuf[0]);
printf("\n!!!\n"); // printf("\n!!!\n");
hw->flags |= tool78_hw_flag_done_reset; // hw->flags |= tool78_hw_flag_done_reset;
//
glitch_disarm(); // glitch_disarm();
goto success; // goto success;
} // }
glitch_disarm(); // glitch_disarm();
//
printf(":"); // printf(":");
do_reset_stuff: //do_reset_stuff:
hw->deinit(); // hw->deinit();
//
// glitch for way too long to power cycle // // glitch for way too long to power cycle
sio_hw->gpio_set = 1u << GLITCH_OUT_PIN; // sio_hw->gpio_set = 1u << GLITCH_OUT_PIN;
busy_wait_ms(16); // busy_wait_ms(16);
sio_hw->gpio_clr = 1u << GLITCH_OUT_PIN; // sio_hw->gpio_clr = 1u << GLITCH_OUT_PIN;
//
goto restart; // goto restart;
//
success:; //success:;
//gpio_put(2, true); // //gpio_put(2, true);
//busy_wait_ms(5); // //busy_wait_ms(5);
// (02): read from above (checkbuf) code // // (02): read from above (checkbuf) code
// 03 06 18 00 df 03 // // 03 06 18 00 df 03
// ^-- baud rate set response // // ^-- baud rate set response
// 00 // // 00
// ^-- OCD entry response // // ^-- OCD entry response
rr = hw->recv(4, &checkbuf[1], 10000); // rr = hw->recv(4, &checkbuf[1], 10000);
if (rr != 4) { // if (rr != 4) {
printf("#"); // printf("#");
//printf("rr=%d, wut?\n", rr); // //printf("rr=%d, wut?\n", rr);
goto do_reset_stuff; // goto do_reset_stuff;
} // }
printf("recv %02x %02x %02x %02x %02x\n", checkbuf[0], checkbuf[1], // printf("recv %02x %02x %02x %02x %02x\n", checkbuf[0], checkbuf[1],
checkbuf[2], checkbuf[3], checkbuf[4]); // checkbuf[2], checkbuf[3], checkbuf[4]);
//
busy_wait_us_32(500); // busy_wait_us_32(500);
//
printf("glitch len: %lu ns\n", *(volatile uint32_t*)&glitch_param_cur.length_ns.cur); // printf("glitch len: %lu ns\n", *(volatile uint32_t*)&glitch_param_cur.length_ns.cur);
/*goto do_reset_stuff;*/ // /*goto do_reset_stuff;*/
//
st = tool78_ocd_connect(hw, passwd); // st = tool78_ocd_connect(hw, passwd);
if (st != 0xf0 && st != 0xf2) { // if (st != 0xf0 && st != 0xf2) {
printf("OCD: connect failed: %d\n", st); // printf("OCD: connect failed: %d\n", st);
goto deinit_bad; // goto deinit_bad;
} // }
printf("connect! 0x%02x\n", st); // printf("connect! 0x%02x\n", st);
//
for (size_t i = 0; i < DUMP_SIZE; i += 256) { // for (size_t i = 0; i < DUMP_SIZE; i += 256) {
st = tool78_ocd_read(hw, 0x8000+i, (uint8_t)0x100, &databuf[i]); // st = tool78_ocd_read(hw, 0x8000+i, (uint8_t)0x100, &databuf[i]);
if (st) { // if (st) {
printf("no read! st=%d\n", st); // printf("no read! st=%d\n", st);
} // }
} // }
for (size_t iii = 0; iii < DUMP_SIZE; ++iii) { // for (size_t iii = 0; iii < DUMP_SIZE; ++iii) {
printf("%02x%s", databuf[iii], ((iii & 0xf) == 0xf) ? "\n" : " "); // printf("%02x%s", databuf[iii], ((iii & 0xf) == 0xf) ? "\n" : " ");
} // }
//
printf("\ndone!\n"); // printf("\ndone!\n");
//
deinit_bad: //deinit_bad:
hw->deinit(); // hw->deinit();
return; // return;
} }

View File

@ -113,7 +113,7 @@ sec: flg=fe bot=03 fsws=0000 fswe=003f
//st = tool78_do_security_release(&tool78_hw_rl78_uart1); //st = tool78_do_security_release(&tool78_hw_rl78_uart1);
//printf("sec rel: 0x%02x\n", st); //printf("sec rel: 0x%02x\n", st);
// one block = 0x400 = 1k // one block = 0x400 = 1k
st = tool78_do_block_erase(hw, 0, -1); /*st = tool78_do_block_erase(hw, 0, -1);
printf("block erase 0: 0x%02x\n", st); printf("block erase 0: 0x%02x\n", st);
st = tool78_do_block_blank_check(hw, 0, 0x3ff, false); st = tool78_do_block_blank_check(hw, 0, 0x3ff, false);
printf("blank check: 0x%02x\n", st); printf("blank check: 0x%02x\n", st);
@ -121,7 +121,7 @@ sec: flg=fe bot=03 fsws=0000 fswe=003f
printf("programming: 0x%02x\n", st); printf("programming: 0x%02x\n", st);
st = tool78_do_verify(hw, 0, 0x3ff, datatoflash); st = tool78_do_verify(hw, 0, 0x3ff, datatoflash);
printf("verify: 0x%02x\n", st); printf("verify: 0x%02x\n", st);*/
/*for (size_t iii = 0; iii < 65536; iii += 0x400) { /*for (size_t iii = 0; iii < 65536; iii += 0x400) {
st = tool78_do_verify(hw, iii+0, iii+0x3ff, &DATA_wfum_flash[iii]); st = tool78_do_verify(hw, iii+0, iii+0x3ff, &DATA_wfum_flash[iii]);
@ -181,7 +181,7 @@ void cli_tool78_ocdtest(void) {
goto deinit_bad; goto deinit_bad;
} }
printf("result: '%c' (0x%02x)\n", checkbuf[0], checkbuf[0]); printf("result: '%c' (0x%02x)\n", checkbuf[0], checkbuf[0]);
busy_wait_ms(1000);
deinit_bad: deinit_bad:
tool78_hw_rl78_uart1.deinit(); tool78_hw_rl78_uart1.deinit();
return; return;

View File

@ -1120,12 +1120,12 @@ int tool78_ocd_connect(struct tool78_hw* hw, const uint8_t passwd[10]) {
return -1; return -1;
} }
connst=stuff[2]; connst=stuff[2];
printf("connst 1=%02x\n", connst); //printf("connst 1=%02x\n", connst);
if (connst == 0xff) { if (connst == 0xff) {
rr = hw->recv(1, &connst, 1000); rr = hw->recv(1, &connst, 1000);
if (rr != 1) return -1; if (rr != 1) return -1;
} }
printf("connst 2=%02x\n", connst); //printf("connst 2=%02x\n", connst);
if (connst == 0xf0 || connst == 0xf4) return connst; if (connst == 0xf0 || connst == 0xf4) return connst;
// connst==0xf1 // connst==0xf1
@ -1134,12 +1134,12 @@ int tool78_ocd_connect(struct tool78_hw* hw, const uint8_t passwd[10]) {
stuff[10] = tool78_calc_ocd_checksum8(10, passwd); stuff[10] = tool78_calc_ocd_checksum8(10, passwd);
} }
busy_wait_ms(1); busy_wait_us_32(100);
rr = hw->send(is_g10 ? 10 : 11, stuff, -1); rr = hw->send(is_g10 ? 10 : 11, stuff, -1);
// stuff[9] is the checksum byte echoed back // stuff[9] is the checksum byte echoed back
rr = hw->recv(2, &stuff[9], 100000); rr = hw->recv(2, &stuff[9], 100000);
printf("ocdpw 2 = %02x %02x\n", stuff[9], stuff[10]); //printf("ocdpw 2 = %02x %02x\n", stuff[9], stuff[10]);
if (rr != 2) { if (rr != 2) {
/*printf("OCDconn2 rr: %d\n", rr); /*printf("OCDconn2 rr: %d\n", rr);
for (int iii = 0; iii < rr; ++iii) { for (int iii = 0; iii < rr; ++iii) {
@ -1147,17 +1147,17 @@ int tool78_ocd_connect(struct tool78_hw* hw, const uint8_t passwd[10]) {
}*/ }*/
return -2; return -2;
} }
if (stuff[9] == 0xff) { // framing error bullshit if (stuff[9] == 0xff && is_g10) { // framing error bullshit
stuff[9] = stuff[10]; stuff[9] = stuff[10];
rr = hw->recv(1, &stuff[10], 100000); rr = hw->recv(1, &stuff[10], 100000);
if (rr != 1) return -2; if (rr != 1) return -2;
} }
printf("ocdpw 3 = %02x %02x\n", stuff[9], stuff[10]); //printf("ocdpw 3 = %02x %02x\n", stuff[9], stuff[10]);
while (stuff[10] == 0) { while (stuff[10] == 0) {
rr = hw->recv(1, &stuff[10], 100000); rr = hw->recv(1, &stuff[10], 100000);
if (rr != 1) return -2; if (rr != 1) return -2;
} }
printf("ocdpw 4 = %02x %02x\n", stuff[9], stuff[10]); //printf("ocdpw 4 = %02x %02x\n", stuff[9], stuff[10]);
/*printf("cksum=0x%02x conn=%02x pw=%02x\n", /*printf("cksum=0x%02x conn=%02x pw=%02x\n",
cksum, connst, stuff[10]);*/ cksum, connst, stuff[10]);*/
@ -1199,6 +1199,7 @@ int tool78_ocd_read(struct tool78_hw* hw, uint16_t off, uint8_t len,
if (rr != 1) return -1; if (rr != 1) return -1;
if (hdr[0] != 0x00) return -3; if (hdr[0] != 0x00) return -3;
busy_wait_us_32(100);
hdr[0] = tool78ocd_cmdg10_read_word; hdr[0] = tool78ocd_cmdg10_read_word;
rr = hw->send(1, hdr, -1); rr = hw->send(1, hdr, -1);
if (rr != 1) return -1; if (rr != 1) return -1;
@ -1233,6 +1234,7 @@ int tool78_ocd_read(struct tool78_hw* hw, uint16_t off, uint8_t len,
if (rr != 1) return -1; if (rr != 1) return -1;
if (hdr[0] != 0x00) return -3; if (hdr[0] != 0x00) return -3;
busy_wait_us_32(100);
hdr[0] = tool78ocd_cmdg10_read_raw; hdr[0] = tool78ocd_cmdg10_read_raw;
rr = hw->send(1, hdr, -1); rr = hw->send(1, hdr, -1);
if (rr != 1) return -1; if (rr != 1) return -1;
@ -1307,6 +1309,7 @@ int tool78_ocd_write(struct tool78_hw* hw, uint16_t addr, uint8_t len,
hdr[0] = tool78ocd_cmdg10_write_word; hdr[0] = tool78ocd_cmdg10_write_word;
hdr[1] = data[0]; // a hdr[1] = data[0]; // a
busy_wait_us_32(100);
rr = hw->send(2, hdr, -1); rr = hw->send(2, hdr, -1);
if (rr != 2) return -1; if (rr != 2) return -1;
@ -1325,8 +1328,8 @@ int tool78_ocd_write(struct tool78_hw* hw, uint16_t addr, uint8_t len,
// command echoed back // command echoed back
rr = hw->recv(4, hdr, 1000); rr = hw->recv(4, hdr, 1000);
/*printf("wr p1: rr=%d %02x %02x %02x %02x\n", rr, hdr[0], printf("wr p1: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
hdr[1], hdr[2], hdr[3]);*/ hdr[1], hdr[2], hdr[3]);
if (rr != 4) return -2; if (rr != 4) return -2;
if (hdr[0] == 0xff) { // frame error bullshit if (hdr[0] == 0xff) { // frame error bullshit
hdr[0] = hdr[1]; hdr[0] = hdr[1];
@ -1335,42 +1338,49 @@ int tool78_ocd_write(struct tool78_hw* hw, uint16_t addr, uint8_t len,
rr = hw->recv(1, &hdr[3], 1000); rr = hw->recv(1, &hdr[3], 1000);
if (rr != 1) return -2; if (rr != 1) return -2;
} }
/*printf("wr p1: rr=%d %02x %02x %02x %02x\n", rr, hdr[0], printf("wr p1: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
hdr[1], hdr[2], hdr[3]);*/ hdr[1], hdr[2], hdr[3]);
// status // status
rr = hw->recv(1, hdr, 1000); rr = hw->recv(1, hdr, 1000);
/*printf("wr p2: rr=%d %02x %02x %02x %02x\n", rr, hdr[0], printf("wr p2: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
hdr[1], hdr[2], hdr[3]);*/ hdr[1], hdr[2], hdr[3]);
if (rr != 1) return -1; if (rr != 1) return -1;
if (hdr[0] == len) { if (hdr[0] == len) {
rr = hw->recv(1, hdr, 1000); rr = hw->recv(1, hdr, 1000);
/*printf("wr p2: rr=%d %02x %02x %02x %02x\n", rr, hdr[0], printf("wr p2: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
hdr[1], hdr[2], hdr[3]);*/ hdr[1], hdr[2], hdr[3]);
if (rr != 1) return -1; if (rr != 1) return -1;
} }
if (hdr[0] != 0x00) return -3; if (hdr[0] != 0x00) return -3;
hdr[0] = tool78ocd_cmdg10_write_raw; hdr[0] = tool78ocd_cmdg10_write_raw;
busy_wait_us_32(100);
rr = hw->send(1, hdr, -1); rr = hw->send(1, hdr, -1);
if (rr != 1) return -1; if (rr != 1) return -1;
rr = hw->recv(1, hdr, 1000); // sigh rr = hw->recv(1, hdr, 1000); // sigh
printf("wr p3: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
hdr[1], hdr[2], hdr[3]);
if (rr != 1) return -1; if (rr != 1) return -1;
/*printf("wr p3: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
hdr[1], hdr[2], hdr[3]);*/
rr = hw->send(len, data, -1); for (int i = 0; i < len; i += 8) {
if (rr != len) return -1; int todo = len - i;
rr = hw->recv(len, NULL, 1000*len); // sigh if (todo > 8) todo = 8;
if (rr != len) return -1;
/*printf("wr p4: rr=%d %02x %02x %02x %02x\n", rr, hdr[0], busy_wait_us_32(100);
hdr[1], hdr[2], hdr[3]);*/ rr = hw->send(todo, &data[i], -1);
if (rr != todo) return -1;
rr = hw->recv(todo, NULL, 1000*todo); // sigh
printf("wr p4: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
hdr[1], hdr[2], hdr[3]);
if (rr != todo) return -1;
}
rr = hw->recv(1, hdr, 1000); rr = hw->recv(1, hdr, 1000);
/*printf("wr p5: rr=%d %02x %02x %02x %02x\n", rr, hdr[0], printf("wr p5: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
hdr[1], hdr[2], hdr[3]); hdr[1], hdr[2], hdr[3]);
printf("recv %d: %02x %02x\n", rr, hdr[0], hdr[1]);*/ printf("recv %d: %02x %02x\n", rr, hdr[0], hdr[1]);
if (rr != 1) return -1; if (rr != 1) return -1;
return (hdr[0] == 0) ? 0 : -2; return (hdr[0] == 0) ? 0 : -2;
@ -1403,9 +1413,10 @@ int tool78_ocd_exec(struct tool78_hw* hw) {
int rr = hw->send(1, hdr, -1); int rr = hw->send(1, hdr, -1);
rr = hw->recv(1, hdr, 1000); // G13 sends status before exec, G10 sends it after
rr = hw->recv(is_g10 ? 1 : 2, hdr, 1000);
if (rr != 1 && rr != 2) return -1; if (rr != 1 && rr != 2) return -1;
//printf("h[0]=0x%02x, h[1]=0x%02x\n", hdr[0], hdr[1]); printf("exec r=%d: h[0]=0x%02x, h[1]=0x%02x\n", rr, hdr[0], hdr[1]);
return 0;//(hdr[0] == cmd) ? 0 : -2; return 0;//(hdr[0] == cmd) ? 0 : -2;
} }

View File

@ -4,7 +4,7 @@ ENTRY(_start)
MEMORY MEMORY
{ {
ram (rwx) : ORIGIN = 0xff900, LENGTH = 0x5e0/*idk*/ ram (rwx) : ORIGIN = 0xffe00, LENGTH = 0x0a0/*idk*/
} }
SECTIONS { SECTIONS {

View File

@ -3,64 +3,63 @@
.global _start .global _start
_start: _start:
movw sp, #0xfe00 ;movw sp, #0xfe00
;di di
mov a, #'a' mov a, #'a'
call !!tool_tx call !!tool_tx
br !!0xeffba
; mov !PIOR, #0 mov !PIOR, #0
; mov P0, #0 mov P0, #0
; mov !PU0, #0 mov !PU0, #0
; mov !POM0, #0 mov !POM0, #0
; mov !PMC0, #0x7f mov !PMC0, #0x7f
; mov !PM0, #0 mov !PM0, #0
;
; mov !PER0, #0xe5 ; enable peripherals mov !PER0, #0xe5 ; enable peripherals
; mov !OSMC, #0x10 mov !OSMC, #0x10
;
;looper: looper:
; mov P0, #0xff mov P0, #0xff
; ;movw ax, #0xfae0 movw ax, #0xfae0
;
;/* mov hl, ax movw hl, ax
; mov c, #0 mov c, #0
;
;1: mov b, #0xff 1: mov b, #0xff
; mov a, #0xff mov a, #0xff
;
;2: inc a 2: inc a
; dec b dec b
; bnz 2b bnz $2b
;
; mov [hl+c], a dec c
; dec c mov [hl+c], a
; bnz 1b bnz $1b
;
; mov P0, #0 mov P0, #0
;
; mov c, #0x18 mov c, #0x18
;3: mov b, #0xff 3: mov b, #0xff
;4: dec b 4: dec b
; bnz 4b bnz $4b
; dec c dec c
; bnz 3b*/ bnz $3b
;
; mov a, #0x48 mov a, #'H'
; call !!tool_tx call !!tool_tx
; mov a, #0x69 mov a, #'i'
; call !!tool_tx call !!tool_tx
;
;/* mov x, #0xaa mov x, #0xaa
; mov c, #0 mov c, #0
;
;5: dec c 5: dec c
; mov a, [hl+c] mov a, [hl+c]
; xor a, x xor a, x
; call !!tool_tx call !!tool_tx
; cmp0 c cmp0 c
; bnz 5b bnz $5b
; br $looper*/ br $looper
;
; ret ret