fix bugs, getting towards RL78/G10 glitching param test
This commit is contained in:
parent
c4bb26ead1
commit
7b40542c20
|
@ -21,8 +21,8 @@ void cli_tool78_glitch_ocd_dump(void);
|
|||
void cli_tool78_glitch_param_g10(void);
|
||||
void cli_tool78_glitch_ocd_g10(void);
|
||||
|
||||
#define DUMP_OFFSET 0/*0xef000*/
|
||||
#define DUMP_SIZE 1024/*65536*/
|
||||
#define DUMP_OFFSET 0xef000
|
||||
#define DUMP_SIZE 4096/*65536*/
|
||||
|
||||
// test with decoupling caps: length in 20..500(..1500) -> ok
|
||||
// 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] = {
|
||||
0x71, 0x7b, 0xfa, 0xf5, 0xf0, 0x02, 0xf5, 0x78, 0x00, 0x71, 0x6a, 0xa4, 0xcf,
|
||||
0x76, 0x00, 0x01, 0xce, 0x22, 0x00, 0xf5, 0x62, 0x00, 0xf5, 0x77, 0x00, 0xf5,
|
||||
0x79, 0x00, 0xf5, 0x75, 0x00, 0xf5, 0x7c, 0x00, 0xce, 0x02, 0x00, 0xce, 0x02,
|
||||
0xff, 0x30, 0x00, 0xfa, 0x16, 0x52, 0x00, 0x53, 0xff, 0x51, 0x00, 0x81, 0x93,
|
||||
0xdf, 0xfc, 0x92, 0x61, 0xf9, 0xdf, 0xf3, 0xce, 0x02, 0x00, 0x52, 0x18, 0x53,
|
||||
0xff, 0x93, 0xdf, 0xfd, 0x92, 0xdf, 0xf8, 0x51, 0x48, 0xfc, 0xa1, 0xff, 0x0e,
|
||||
0x51, 0x69, 0xfc, 0xa1, 0xff, 0x0e, 0x50, 0xaa, 0x52, 0x00, 0x92, 0x61, 0xe9,
|
||||
0x61, 0x78, 0xfc, 0xa1, 0xff, 0x0e, 0xd2, 0xdf, 0xf4, 0xef, 0xbf
|
||||
0x71, 0x7b, 0xfa, 0xf5, 0xf0, 0x02, 0xf5, 0x78, 0x00, 0x71, 0x6a, 0xa4,
|
||||
0xcf, 0x76, 0x00, 0x01, 0xce, 0x22, 0x00, 0xf5, 0x62, 0x00, 0xf5, 0x77,
|
||||
0x00, 0xf5, 0x79, 0x00, 0xf5, 0x75, 0x00, 0xf5, 0x7c, 0x00, 0xce, 0x02,
|
||||
0x00, 0xce, 0x02, 0xff, 0x30, 0x00, 0xfa, 0x16, 0x52, 0x00, 0x53, 0xff,
|
||||
0x51, 0x00, 0x81, 0x93, 0xdf, 0xfc, 0x92, 0x61, 0xf9, 0xdf, 0xf3, 0xce,
|
||||
0x02, 0x00, 0x52, 0x18, 0x53, 0xff, 0x93, 0xdf, 0xfd, 0x92, 0xdf, 0xf8,
|
||||
0x51, 0x48, 0xfc, 0xa1, 0xff, 0x0e, 0x51, 0x69, 0xfc, 0xa1, 0xff, 0x0e,
|
||||
0x50, 0xaa, 0x52, 0x00, 0x92, 0x61, 0xe9, 0x61, 0x78, 0xfc, 0xa1, 0xff,
|
||||
0x0e, 0xd2, 0xdf, 0xf4, 0xef, 0xbf
|
||||
};
|
||||
|
||||
static uint8_t dumper_shellcode[0x26] = {
|
||||
//0xe0, 0x07, 0x26, // 0xF07E0 location, 0x26 length of packet
|
||||
0x41, 0x00, 0x34, 0x00, 0x00, 0x00, 0x11, 0x89, 0xFC, 0xA1, 0xFF, 0x0E, 0xA5, 0x15, 0x44,
|
||||
0x00, 0x00, 0xDF, 0xF3, 0xEF, 0x04, 0x55, 0x00, 0x00, 0x00, 0x8E, 0xFD, 0x81, 0x5C, 0x0F,
|
||||
0x9E, 0xFD, 0x71, 0x00, 0x90, 0x00, 0xEF, 0xE0
|
||||
0x41, 0x00, 0x34, 0x00, 0x00, 0x00, 0x11, 0x89, 0xFC, 0xA1, 0xFF, 0x0E, 0xA5,
|
||||
0x15, 0x44, 0x00, 0x00, 0xDF, 0xF3, 0xEF, 0x04, 0x55, 0x00, 0x00, 0x00, 0x8E,
|
||||
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) {
|
||||
uint8_t passwd[10] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
uint16_t ver;
|
||||
|
@ -537,13 +559,12 @@ deinit_bad:
|
|||
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,
|
||||
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,
|
||||
0x0e, 0x51, 0x69, 0xfc, 0xdc, 0xff, 0x0e, 0xd7
|
||||
};
|
||||
|
||||
};*/
|
||||
|
||||
void cli_tool78_glitch_param_g10(void) {
|
||||
struct tool78_hw* hw = &tool78_hw_rl78g10_uart1;
|
||||
|
@ -592,45 +613,62 @@ restart:
|
|||
}
|
||||
if (first) printf("result: 0x%02x\n", st);
|
||||
|
||||
// TODO: upload other code!
|
||||
// can't write too much at 0xf07e0 as 0xf0800 and up contains OCD state,
|
||||
// overwrite this and suddenly the OCD system resets itself
|
||||
st = tool78_ocd_write(hw, 0x07e0,
|
||||
sizeof(exec_jmp_to_ram), exec_jmp_to_ram);
|
||||
st = tool78_ocd_write(hw, 0xfed0,
|
||||
sizeof(G1M_payload_1), G1M_payload_1);
|
||||
//printf("write trampoline res 0x%02x\n", st);
|
||||
if (st != 0) {
|
||||
printf("trampoline write failed: %d\n", st);
|
||||
printf("payload 1 write failed: %d\n", st);
|
||||
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);
|
||||
//printf("exec res 0x%02x\n", st);
|
||||
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;
|
||||
}
|
||||
|
||||
// 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
|
||||
rr = hw->recv(2, checkbuf, 120*1000);
|
||||
if (rr != 2) {
|
||||
printf("exec code: no response :/ (%d)\n", rr);
|
||||
printf("exec code hdr: no response :/ (%d)\n", rr);
|
||||
goto deinit_bad;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -650,9 +688,9 @@ restart:
|
|||
first = false;
|
||||
|
||||
while (true) {
|
||||
glitch_arm();
|
||||
//glitch_arm();
|
||||
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) {
|
||||
rr = hw->recv(256, checkbuf, 120*1000);
|
||||
|
@ -682,12 +720,13 @@ restart:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
deinit_bad:
|
||||
busy_wait_ms(1000);
|
||||
hw->deinit();
|
||||
return;
|
||||
|
||||
do_reset_stuff:
|
||||
busy_wait_ms(1000);
|
||||
hw->deinit();
|
||||
|
||||
// glitch for way too long to power cycle
|
||||
|
@ -699,157 +738,157 @@ do_reset_stuff:
|
|||
}
|
||||
|
||||
void cli_tool78_glitch_ocd_g10(void) {
|
||||
struct tool78_hw* hw = &tool78_hw_rl78g10_uart1;
|
||||
|
||||
zap_dac_set_enable(zap_dac_a | zap_dac_b);
|
||||
#if 1 /* MCP48x2 */
|
||||
zap_dac_set_mulx2(zap_dac_a | zap_dac_b);
|
||||
#else
|
||||
zap_dac_set_mulx2(0);
|
||||
zap_dac_set_shutdown(false);
|
||||
#endif
|
||||
|
||||
zap_max_use_vhi_jp300(true);
|
||||
zap_max_set_inhibit(false);
|
||||
|
||||
if (!glitch_init_core1_stuff(false, ZAP_GLITCH_OUT)) {
|
||||
printf("bad glitcher params!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
gpio_set_function(2, GPIO_FUNC_SIO);
|
||||
gpio_set_dir(2, GPIO_OUT);
|
||||
gpio_put(2, false);
|
||||
|
||||
//gpio_set_function(3, GPIO_FUNC_SIO);
|
||||
//gpio_set_dir(3, GPIO_OUT);
|
||||
//gpio_put(3, false);
|
||||
|
||||
uint8_t passwd[10] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
int st, rr/*, r0, r1, r2*/;
|
||||
static uint8_t checkbuf[256];
|
||||
bool first = true;
|
||||
|
||||
restart:
|
||||
//trl78_uart1_set_exclusive(true);
|
||||
//hw->rx_set_stop_bit(false);
|
||||
gpio_put(2, false);
|
||||
/*glitch_disarm();
|
||||
busy_wait_ms(40);*/
|
||||
|
||||
st = tool78_init_ocd(hw, NULL, passwd);
|
||||
if (st == 0xc3) {
|
||||
printf("aa\n");
|
||||
st = 0;
|
||||
rr = hw->recv(1, (uint8_t*)&st, 120*1000);
|
||||
printf("rr=%d\n", rr);
|
||||
if (rr != 1) {
|
||||
printf("aaaa\n");
|
||||
goto do_reset_stuff;
|
||||
}
|
||||
}
|
||||
if (first) printf("result: 0x%02x\n", st);
|
||||
if (st == 0xc1) goto do_reset_stuff;
|
||||
if (st != tool78_stat_no_ocd_status) {
|
||||
printf("init: expected status timeout error, got %d\n", st);
|
||||
goto deinit_bad;
|
||||
}
|
||||
busy_wait_ms(16); // leave time to recharge
|
||||
|
||||
// TODO: update description
|
||||
// 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
|
||||
// right below it, so we can simply try to glitch it without having to meet
|
||||
// the timing
|
||||
// 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
|
||||
// that had no effect. after 16 iterations without result, reset the RL78
|
||||
// and try again.
|
||||
// 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
|
||||
// the MCU flash automatically? somehow?? I suppose it's the WDT
|
||||
if (first) printf("all set, let's go\n");
|
||||
first = false;
|
||||
|
||||
//hw->rx_set_stop_bit(false);
|
||||
glitch_arm();
|
||||
for (size_t i = 0; i < 16; ++i) {
|
||||
zap_dac_set_b(zap_adc_read(1));
|
||||
zap_dac_latch();
|
||||
//glitch_trigger_sw_core1();
|
||||
glitch_trigger_sw_pio();
|
||||
rr = hw->recv(1, checkbuf, 12*1000);
|
||||
if (rr != 1 || checkbuf[0] == 0xff) {
|
||||
busy_wait_ms(1); // leave time to recharge
|
||||
printf(".");
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("checkbuf: %d", checkbuf[0]);
|
||||
printf("\n!!!\n");
|
||||
hw->flags |= tool78_hw_flag_done_reset;
|
||||
|
||||
glitch_disarm();
|
||||
goto success;
|
||||
}
|
||||
glitch_disarm();
|
||||
|
||||
printf(":");
|
||||
do_reset_stuff:
|
||||
hw->deinit();
|
||||
|
||||
// glitch for way too long to power cycle
|
||||
sio_hw->gpio_set = 1u << GLITCH_OUT_PIN;
|
||||
busy_wait_ms(16);
|
||||
sio_hw->gpio_clr = 1u << GLITCH_OUT_PIN;
|
||||
|
||||
goto restart;
|
||||
|
||||
success:;
|
||||
//gpio_put(2, true);
|
||||
//busy_wait_ms(5);
|
||||
// (02): read from above (checkbuf) code
|
||||
// 03 06 18 00 df 03
|
||||
// ^-- baud rate set response
|
||||
// 00
|
||||
// ^-- OCD entry response
|
||||
rr = hw->recv(4, &checkbuf[1], 10000);
|
||||
if (rr != 4) {
|
||||
printf("#");
|
||||
//printf("rr=%d, wut?\n", rr);
|
||||
goto do_reset_stuff;
|
||||
}
|
||||
printf("recv %02x %02x %02x %02x %02x\n", checkbuf[0], checkbuf[1],
|
||||
checkbuf[2], checkbuf[3], checkbuf[4]);
|
||||
|
||||
busy_wait_us_32(500);
|
||||
|
||||
printf("glitch len: %lu ns\n", *(volatile uint32_t*)&glitch_param_cur.length_ns.cur);
|
||||
/*goto do_reset_stuff;*/
|
||||
|
||||
st = tool78_ocd_connect(hw, passwd);
|
||||
if (st != 0xf0 && st != 0xf2) {
|
||||
printf("OCD: connect failed: %d\n", st);
|
||||
goto deinit_bad;
|
||||
}
|
||||
printf("connect! 0x%02x\n", st);
|
||||
|
||||
for (size_t i = 0; i < DUMP_SIZE; i += 256) {
|
||||
st = tool78_ocd_read(hw, 0x8000+i, (uint8_t)0x100, &databuf[i]);
|
||||
if (st) {
|
||||
printf("no read! st=%d\n", st);
|
||||
}
|
||||
}
|
||||
for (size_t iii = 0; iii < DUMP_SIZE; ++iii) {
|
||||
printf("%02x%s", databuf[iii], ((iii & 0xf) == 0xf) ? "\n" : " ");
|
||||
}
|
||||
|
||||
printf("\ndone!\n");
|
||||
|
||||
deinit_bad:
|
||||
hw->deinit();
|
||||
return;
|
||||
// struct tool78_hw* hw = &tool78_hw_rl78g10_uart1;
|
||||
//
|
||||
// zap_dac_set_enable(zap_dac_a | zap_dac_b);
|
||||
//#if 1 /* MCP48x2 */
|
||||
// zap_dac_set_mulx2(zap_dac_a | zap_dac_b);
|
||||
//#else
|
||||
// zap_dac_set_mulx2(0);
|
||||
// zap_dac_set_shutdown(false);
|
||||
//#endif
|
||||
//
|
||||
// zap_max_use_vhi_jp300(true);
|
||||
// zap_max_set_inhibit(false);
|
||||
//
|
||||
// if (!glitch_init_core1_stuff(false, ZAP_GLITCH_OUT)) {
|
||||
// printf("bad glitcher params!\n");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// gpio_set_function(2, GPIO_FUNC_SIO);
|
||||
// gpio_set_dir(2, GPIO_OUT);
|
||||
// gpio_put(2, false);
|
||||
//
|
||||
// //gpio_set_function(3, GPIO_FUNC_SIO);
|
||||
// //gpio_set_dir(3, GPIO_OUT);
|
||||
// //gpio_put(3, false);
|
||||
//
|
||||
// uint8_t passwd[10] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
// int st, rr/*, r0, r1, r2*/;
|
||||
// static uint8_t checkbuf[256];
|
||||
// bool first = true;
|
||||
//
|
||||
//restart:
|
||||
// //trl78_uart1_set_exclusive(true);
|
||||
// //hw->rx_set_stop_bit(false);
|
||||
// gpio_put(2, false);
|
||||
// /*glitch_disarm();
|
||||
// busy_wait_ms(40);*/
|
||||
//
|
||||
// st = tool78_init_ocd(hw, NULL, passwd);
|
||||
// if (st == 0xc3) {
|
||||
// printf("aa\n");
|
||||
// st = 0;
|
||||
// rr = hw->recv(1, (uint8_t*)&st, 120*1000);
|
||||
// printf("rr=%d\n", rr);
|
||||
// if (rr != 1) {
|
||||
// printf("aaaa\n");
|
||||
// goto do_reset_stuff;
|
||||
// }
|
||||
// }
|
||||
// if (first) printf("result: 0x%02x\n", st);
|
||||
// if (st == 0xc1) goto do_reset_stuff;
|
||||
// if (st != tool78_stat_no_ocd_status) {
|
||||
// printf("init: expected status timeout error, got %d\n", st);
|
||||
// goto deinit_bad;
|
||||
// }
|
||||
// busy_wait_ms(16); // leave time to recharge
|
||||
//
|
||||
// // TODO: update description
|
||||
// // 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
|
||||
// // right below it, so we can simply try to glitch it without having to meet
|
||||
// // the timing
|
||||
// // 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
|
||||
// // that had no effect. after 16 iterations without result, reset the RL78
|
||||
// // and try again.
|
||||
// // 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
|
||||
// // the MCU flash automatically? somehow?? I suppose it's the WDT
|
||||
// if (first) printf("all set, let's go\n");
|
||||
// first = false;
|
||||
//
|
||||
// //hw->rx_set_stop_bit(false);
|
||||
// glitch_arm();
|
||||
// for (size_t i = 0; i < 16; ++i) {
|
||||
// zap_dac_set_b(zap_adc_read(1));
|
||||
// zap_dac_latch();
|
||||
// //glitch_trigger_sw_core1();
|
||||
// glitch_trigger_sw_pio();
|
||||
// rr = hw->recv(1, checkbuf, 12*1000);
|
||||
// if (rr != 1 || checkbuf[0] == 0xff) {
|
||||
// busy_wait_ms(1); // leave time to recharge
|
||||
// printf(".");
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// printf("checkbuf: %d", checkbuf[0]);
|
||||
// printf("\n!!!\n");
|
||||
// hw->flags |= tool78_hw_flag_done_reset;
|
||||
//
|
||||
// glitch_disarm();
|
||||
// goto success;
|
||||
// }
|
||||
// glitch_disarm();
|
||||
//
|
||||
// printf(":");
|
||||
//do_reset_stuff:
|
||||
// hw->deinit();
|
||||
//
|
||||
// // glitch for way too long to power cycle
|
||||
// sio_hw->gpio_set = 1u << GLITCH_OUT_PIN;
|
||||
// busy_wait_ms(16);
|
||||
// sio_hw->gpio_clr = 1u << GLITCH_OUT_PIN;
|
||||
//
|
||||
// goto restart;
|
||||
//
|
||||
//success:;
|
||||
// //gpio_put(2, true);
|
||||
// //busy_wait_ms(5);
|
||||
// // (02): read from above (checkbuf) code
|
||||
// // 03 06 18 00 df 03
|
||||
// // ^-- baud rate set response
|
||||
// // 00
|
||||
// // ^-- OCD entry response
|
||||
// rr = hw->recv(4, &checkbuf[1], 10000);
|
||||
// if (rr != 4) {
|
||||
// printf("#");
|
||||
// //printf("rr=%d, wut?\n", rr);
|
||||
// goto do_reset_stuff;
|
||||
// }
|
||||
// printf("recv %02x %02x %02x %02x %02x\n", checkbuf[0], checkbuf[1],
|
||||
// checkbuf[2], checkbuf[3], checkbuf[4]);
|
||||
//
|
||||
// busy_wait_us_32(500);
|
||||
//
|
||||
// printf("glitch len: %lu ns\n", *(volatile uint32_t*)&glitch_param_cur.length_ns.cur);
|
||||
// /*goto do_reset_stuff;*/
|
||||
//
|
||||
// st = tool78_ocd_connect(hw, passwd);
|
||||
// if (st != 0xf0 && st != 0xf2) {
|
||||
// printf("OCD: connect failed: %d\n", st);
|
||||
// goto deinit_bad;
|
||||
// }
|
||||
// printf("connect! 0x%02x\n", st);
|
||||
//
|
||||
// for (size_t i = 0; i < DUMP_SIZE; i += 256) {
|
||||
// st = tool78_ocd_read(hw, 0x8000+i, (uint8_t)0x100, &databuf[i]);
|
||||
// if (st) {
|
||||
// printf("no read! st=%d\n", st);
|
||||
// }
|
||||
// }
|
||||
// for (size_t iii = 0; iii < DUMP_SIZE; ++iii) {
|
||||
// printf("%02x%s", databuf[iii], ((iii & 0xf) == 0xf) ? "\n" : " ");
|
||||
// }
|
||||
//
|
||||
// printf("\ndone!\n");
|
||||
//
|
||||
//deinit_bad:
|
||||
// hw->deinit();
|
||||
// return;
|
||||
}
|
||||
|
||||
|
|
|
@ -113,7 +113,7 @@ sec: flg=fe bot=03 fsws=0000 fswe=003f
|
|||
//st = tool78_do_security_release(&tool78_hw_rl78_uart1);
|
||||
//printf("sec rel: 0x%02x\n", st);
|
||||
// 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);
|
||||
st = tool78_do_block_blank_check(hw, 0, 0x3ff, false);
|
||||
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);
|
||||
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
printf("result: '%c' (0x%02x)\n", checkbuf[0], checkbuf[0]);
|
||||
|
||||
busy_wait_ms(1000);
|
||||
deinit_bad:
|
||||
tool78_hw_rl78_uart1.deinit();
|
||||
return;
|
||||
|
|
|
@ -1120,12 +1120,12 @@ int tool78_ocd_connect(struct tool78_hw* hw, const uint8_t passwd[10]) {
|
|||
return -1;
|
||||
}
|
||||
connst=stuff[2];
|
||||
printf("connst 1=%02x\n", connst);
|
||||
//printf("connst 1=%02x\n", connst);
|
||||
if (connst == 0xff) {
|
||||
rr = hw->recv(1, &connst, 1000);
|
||||
if (rr != 1) return -1;
|
||||
}
|
||||
printf("connst 2=%02x\n", connst);
|
||||
//printf("connst 2=%02x\n", connst);
|
||||
if (connst == 0xf0 || connst == 0xf4) return connst;
|
||||
// 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);
|
||||
}
|
||||
|
||||
busy_wait_ms(1);
|
||||
busy_wait_us_32(100);
|
||||
rr = hw->send(is_g10 ? 10 : 11, stuff, -1);
|
||||
|
||||
// stuff[9] is the checksum byte echoed back
|
||||
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) {
|
||||
/*printf("OCDconn2 rr: %d\n", rr);
|
||||
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;
|
||||
}
|
||||
if (stuff[9] == 0xff) { // framing error bullshit
|
||||
if (stuff[9] == 0xff && is_g10) { // framing error bullshit
|
||||
stuff[9] = stuff[10];
|
||||
rr = hw->recv(1, &stuff[10], 100000);
|
||||
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) {
|
||||
rr = hw->recv(1, &stuff[10], 100000);
|
||||
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",
|
||||
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 (hdr[0] != 0x00) return -3;
|
||||
|
||||
busy_wait_us_32(100);
|
||||
hdr[0] = tool78ocd_cmdg10_read_word;
|
||||
rr = hw->send(1, hdr, -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 (hdr[0] != 0x00) return -3;
|
||||
|
||||
busy_wait_us_32(100);
|
||||
hdr[0] = tool78ocd_cmdg10_read_raw;
|
||||
rr = hw->send(1, hdr, -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[1] = data[0]; // a
|
||||
|
||||
busy_wait_us_32(100);
|
||||
rr = hw->send(2, hdr, -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
|
||||
rr = hw->recv(4, hdr, 1000);
|
||||
/*printf("wr p1: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
|
||||
hdr[1], hdr[2], hdr[3]);*/
|
||||
printf("wr p1: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
|
||||
hdr[1], hdr[2], hdr[3]);
|
||||
if (rr != 4) return -2;
|
||||
if (hdr[0] == 0xff) { // frame error bullshit
|
||||
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);
|
||||
if (rr != 1) return -2;
|
||||
}
|
||||
/*printf("wr p1: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
|
||||
hdr[1], hdr[2], hdr[3]);*/
|
||||
printf("wr p1: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
|
||||
hdr[1], hdr[2], hdr[3]);
|
||||
|
||||
// status
|
||||
rr = hw->recv(1, hdr, 1000);
|
||||
/*printf("wr p2: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
|
||||
hdr[1], hdr[2], hdr[3]);*/
|
||||
printf("wr p2: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
|
||||
hdr[1], hdr[2], hdr[3]);
|
||||
if (rr != 1) return -1;
|
||||
if (hdr[0] == len) {
|
||||
rr = hw->recv(1, hdr, 1000);
|
||||
/*printf("wr p2: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
|
||||
hdr[1], hdr[2], hdr[3]);*/
|
||||
printf("wr p2: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
|
||||
hdr[1], hdr[2], hdr[3]);
|
||||
if (rr != 1) return -1;
|
||||
}
|
||||
if (hdr[0] != 0x00) return -3;
|
||||
|
||||
hdr[0] = tool78ocd_cmdg10_write_raw;
|
||||
|
||||
busy_wait_us_32(100);
|
||||
rr = hw->send(1, hdr, -1);
|
||||
if (rr != 1) return -1;
|
||||
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;
|
||||
/*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);
|
||||
if (rr != len) return -1;
|
||||
rr = hw->recv(len, NULL, 1000*len); // sigh
|
||||
if (rr != len) return -1;
|
||||
/*printf("wr p4: rr=%d %02x %02x %02x %02x\n", rr, hdr[0],
|
||||
hdr[1], hdr[2], hdr[3]);*/
|
||||
for (int i = 0; i < len; i += 8) {
|
||||
int todo = len - i;
|
||||
if (todo > 8) todo = 8;
|
||||
|
||||
busy_wait_us_32(100);
|
||||
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);
|
||||
/*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]);
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
//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;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ ENTRY(_start)
|
|||
|
||||
MEMORY
|
||||
{
|
||||
ram (rwx) : ORIGIN = 0xff900, LENGTH = 0x5e0/*idk*/
|
||||
ram (rwx) : ORIGIN = 0xffe00, LENGTH = 0x0a0/*idk*/
|
||||
}
|
||||
|
||||
SECTIONS {
|
||||
|
|
|
@ -3,64 +3,63 @@
|
|||
|
||||
.global _start
|
||||
_start:
|
||||
movw sp, #0xfe00
|
||||
;di
|
||||
;movw sp, #0xfe00
|
||||
di
|
||||
|
||||
mov a, #'a'
|
||||
call !!tool_tx
|
||||
br !!0xeffba
|
||||
|
||||
; mov !PIOR, #0
|
||||
; mov P0, #0
|
||||
; mov !PU0, #0
|
||||
; mov !POM0, #0
|
||||
; mov !PMC0, #0x7f
|
||||
; mov !PM0, #0
|
||||
;
|
||||
; mov !PER0, #0xe5 ; enable peripherals
|
||||
; mov !OSMC, #0x10
|
||||
;
|
||||
;looper:
|
||||
; mov P0, #0xff
|
||||
; ;movw ax, #0xfae0
|
||||
;
|
||||
;/* mov hl, ax
|
||||
; mov c, #0
|
||||
;
|
||||
;1: mov b, #0xff
|
||||
; mov a, #0xff
|
||||
;
|
||||
;2: inc a
|
||||
; dec b
|
||||
; bnz 2b
|
||||
;
|
||||
; mov [hl+c], a
|
||||
; dec c
|
||||
; bnz 1b
|
||||
;
|
||||
; mov P0, #0
|
||||
;
|
||||
; mov c, #0x18
|
||||
;3: mov b, #0xff
|
||||
;4: dec b
|
||||
; bnz 4b
|
||||
; dec c
|
||||
; bnz 3b*/
|
||||
;
|
||||
; mov a, #0x48
|
||||
; call !!tool_tx
|
||||
; mov a, #0x69
|
||||
; call !!tool_tx
|
||||
;
|
||||
;/* mov x, #0xaa
|
||||
; mov c, #0
|
||||
;
|
||||
;5: dec c
|
||||
; mov a, [hl+c]
|
||||
; xor a, x
|
||||
; call !!tool_tx
|
||||
; cmp0 c
|
||||
; bnz 5b
|
||||
; br $looper*/
|
||||
;
|
||||
; ret
|
||||
mov !PIOR, #0
|
||||
mov P0, #0
|
||||
mov !PU0, #0
|
||||
mov !POM0, #0
|
||||
mov !PMC0, #0x7f
|
||||
mov !PM0, #0
|
||||
|
||||
mov !PER0, #0xe5 ; enable peripherals
|
||||
mov !OSMC, #0x10
|
||||
|
||||
looper:
|
||||
mov P0, #0xff
|
||||
movw ax, #0xfae0
|
||||
|
||||
movw hl, ax
|
||||
mov c, #0
|
||||
|
||||
1: mov b, #0xff
|
||||
mov a, #0xff
|
||||
|
||||
2: inc a
|
||||
dec b
|
||||
bnz $2b
|
||||
|
||||
dec c
|
||||
mov [hl+c], a
|
||||
bnz $1b
|
||||
|
||||
mov P0, #0
|
||||
|
||||
mov c, #0x18
|
||||
3: mov b, #0xff
|
||||
4: dec b
|
||||
bnz $4b
|
||||
dec c
|
||||
bnz $3b
|
||||
|
||||
mov a, #'H'
|
||||
call !!tool_tx
|
||||
mov a, #'i'
|
||||
call !!tool_tx
|
||||
|
||||
mov x, #0xaa
|
||||
mov c, #0
|
||||
|
||||
5: dec c
|
||||
mov a, [hl+c]
|
||||
xor a, x
|
||||
call !!tool_tx
|
||||
cmp0 c
|
||||
bnz $5b
|
||||
br $looper
|
||||
|
||||
ret
|
||||
|
|
Loading…
Reference in New Issue