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_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;
}

View File

@ -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;

View File

@ -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;
}

View File

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

View File

@ -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