From 8820a9b40e0d499407b5648982737a8ba8dd1359 Mon Sep 17 00:00:00 2001 From: sys64738 Date: Mon, 18 Jul 2022 11:38:06 +0200 Subject: [PATCH] rl78/g23 probe and glitching routines --- src/bsp/pinout.h | 4 +- src/cli/cli.c | 6 + src/cli/rl78-glitch.c | 397 ++++++++++++++++++++++++++++++++++--- src/cli/rl78.c | 35 +++- src/glitch/glitch.c | 8 +- src/tool78/tool78_cmds.c | 8 +- src/tool78/tool78_defs.h | 8 +- test/rl78/test.S | 136 +------------ test/rl78/test_g13_param.S | 91 +++++++++ test/rl78/test_g23_ocd.S | 41 ++++ test/rl78/test_g23_param.S | 106 ++++++++++ test/rl78/test_old.S | 135 +++++++++++++ 12 files changed, 801 insertions(+), 174 deletions(-) mode change 100644 => 120000 test/rl78/test.S create mode 100644 test/rl78/test_g13_param.S create mode 100644 test/rl78/test_g23_ocd.S create mode 100644 test/rl78/test_g23_param.S create mode 100644 test/rl78/test_old.S diff --git a/src/bsp/pinout.h b/src/bsp/pinout.h index 0a61ab3..52b9e3e 100644 --- a/src/bsp/pinout.h +++ b/src/bsp/pinout.h @@ -11,7 +11,7 @@ #define TRIGGER_IN_PIN ZAP_TRIG_IN // use CROWBAR_1 / CROWBAR_2 / GLITCH_OUT to select glitching method -#define GLITCH_OUT_PIN ZAP_CROWBAR_1 +#define GLITCH_OUT_PIN ZAP_GLITCH_OUT/*ZAP_CROWBAR_1*/ #define PINOUT_SBW_PIO BREADBOARD_SBW_PIO #define PINOUT_SBW_TCK (ZAP_GPIO_BASE+0) @@ -33,7 +33,7 @@ #define PINOUT_TOOL78_78K0R_FLMD0 (ZAP_GPIO_BASE+1) #define PINOUT_TOOL78_78K0R_TOOL0 (ZAP_GPIO_BASE+2) -#define PINOUT_TOOL78_RL78_TOOL0 (ZAP_GPIO_BASE+1) +#define PINOUT_TOOL78_RL78_TOOL0 (ZAP_GPIO_BASE+1) /* welp, lvl shifter pin2 is dead(?) */ #define PINOUT_TOOL78_RL78_TX (ZAP_GPIO_BASE+2) #define PINOUT_TOOL78_RL78_RX (ZAP_GPIO_BASE+3) diff --git a/src/cli/cli.c b/src/cli/cli.c index f67a3df..ed2b902 100644 --- a/src/cli/cli.c +++ b/src/cli/cli.c @@ -33,8 +33,11 @@ void cli_tool78_g10_prototest(void); void cli_tool78_g10_ocdtest(void); void cli_tool78_glitch_dump(void); +void cli_tool78_glitch_dump_g23(void); void cli_tool78_glitch_paramsearch(void); +void cli_tool78_glitch_param_g23(void); void cli_tool78_glitch_ocd_dump(void); +void cli_tool78_glitch_ocd_dump_g23(void); void cli_tool78_glitch_param_g10(void); void cli_tool78_glitch_ocd_g10(void); @@ -85,8 +88,11 @@ static struct cli_cmd cmds[] = { { "rl10ocd", cli_tool78_g10_ocdtest }, { "g78dump", cli_tool78_glitch_dump }, + { "g23dump", cli_tool78_glitch_dump_g23 }, { "g78param", cli_tool78_glitch_paramsearch }, + { "g23param", cli_tool78_glitch_param_g23 }, { "g78ocd", cli_tool78_glitch_ocd_dump }, + { "g23ocd", cli_tool78_glitch_ocd_dump_g23 }, { "g10param", cli_tool78_glitch_param_g10 }, { "g10ocd", cli_tool78_glitch_ocd_g10 }, diff --git a/src/cli/rl78-glitch.c b/src/cli/rl78-glitch.c index 290f66f..364c025 100644 --- a/src/cli/rl78-glitch.c +++ b/src/cli/rl78-glitch.c @@ -16,13 +16,19 @@ #include "glitch.h" void cli_tool78_glitch_dump(void); +void cli_tool78_glitch_dump_g23(void); void cli_tool78_glitch_paramsearch(void); +void cli_tool78_glitch_param_g23(void); void cli_tool78_glitch_ocd_dump(void); +void cli_tool78_glitch_ocd_dump_g23(void); void cli_tool78_glitch_param_g10(void); void cli_tool78_glitch_ocd_g10(void); -#define DUMP_OFFSET 0xef000 -#define DUMP_SIZE 4096/*65536*/ +#define USE_PICOEMP 0 +#define LEN_USE_ADC 0 + +#define DUMP_OFFSET /*0*//*0xee000*/ +#define DUMP_SIZE /*0x100*/8192/*65536*/ // test with decoupling caps: length in 20..500(..1500) -> ok // testing on ocd lock: length: 5..35 @@ -45,25 +51,37 @@ sec: flg=fe bot=03 fsws=0000 fswe=003f static uint8_t databuf[DUMP_SIZE]; static struct glitch_param_randrange offset; -static struct glitch_param_randrange/*adc*/ length; +#if LEN_USE_ADC +static struct glitch_param_adc length; +#else +static struct glitch_param_randrange length; +#endif //static struct glitch_param_const length; +#define LENGTH_1 (50/*26*1000/3*/) +#define LENGTH_2 (40/*LENGTH_1/2*/) + static bool glitch_init_core1_stuff(bool exttrig, uint glitchpin) { offset.min = 10*1000; - offset.max = 35433*1000; - length.min = 100; - length.max = /*10*50*/26*1000; + offset.max = 35433*1000/25; + length.min = 25;//100; + length.max = /*10*50*/LENGTH_1; //length.value = 5*1000; // 5 us +#if LEN_USE_ADC #if PINOUT_USE_DRAGONZAP - //length.adc_index = 0;//999; + length.adc_index = 0;//999; #else - //length.adc_index = 999; + length.adc_index = 999; +#endif #endif glitch_param_randrange_init(&offset); //glitch_param_const_init(&length); +#if LEN_USE_ADC + glitch_param_adc_init(&length); +#else glitch_param_randrange_init(&length); - //glitch_param_adc_init(&length); +#endif // REGC = 2.11V / 0.47..1 uF // WUFM: REGC = 1.80V // BUT: OCD mode: always 2.1! static struct glitch_params gparam = (struct glitch_params){ @@ -98,7 +116,11 @@ static bool glitch_init_core1_stuff(bool exttrig, uint glitchpin) { }; gparam.length_ns = (struct glitch_param){ .ud = &length, - .getter = glitch_param_randrange_fn,//adc_fn +#if LEN_USE_ADC + .getter = glitch_param_adc_fn +#else + .getter = glitch_param_randrange_fn +#endif }; gparam.trigger_in_pin = exttrig ? TRIGGER_IN_PIN/*7*/ : (-1); return glitch_ready(&gparam); @@ -137,13 +159,50 @@ static uint8_t DATA_test_dbg__paramtest[102] = { 0x0e, 0xd2, 0xdf, 0xf4, 0xef, 0xbf }; +static uint8_t DATA_test_dbg__paramtest_g23[] = { + 0x71, 0x7b, 0xfa, 0xf5, 0xf0, 0x02, 0xf5, 0x78, 0x00, 0xce, 0x22, 0x00, 0xf5, + 0x62, 0x00, 0xf5, 0x77, 0x00, 0xf5, 0x79, 0x00, 0xf5, 0x75, 0x00, 0xf5, 0x7c, + 0x00, 0xf4, 0x02, 0xcb, 0xf8, 0x00, 0xfe, 0xce, 0x02, 0xff, 0xce, 0x02, 0xff, + 0x30, 0x00, 0xc0, 0x30, 0x00, 0xc0, 0x16, 0x16, 0x52, 0x00, 0x53, 0xff, 0x51, + 0x00, 0x81, 0x93, 0xdf, 0xfc, 0x92, 0x61, 0xf9, 0xdf, 0xf3, 0xf4, 0x02, 0xf4, + 0x02, 0x52, 0x18, 0x53, 0xff, 0x93, 0xdf, 0xfd, 0x92, 0xdf, 0xf8, 0x51, 0x48, + 0xfe, 0x16, 0x00, 0x51, 0x69, 0xfe, 0x11, 0x00, 0x50, 0xaa, 0x52, 0x00, 0x92, + 0x61, 0xe9, 0x61, 0x78, 0xfe, 0x05, 0x00, 0xd2, 0xdf, 0xf5, 0xef, 0xba, 0x71, + 0x7a, 0xaf, 0x00, 0x9e, 0xad, 0x31, 0xb4, 0xaf, 0xfc, 0x71, 0x3b, 0xaf, 0x71, + 0x7b, 0xaf, 0xd7 +}; + + 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, // mov es, #0 + 0x34, 0x00, 0x00, // movw de, #0 +// next: + 0x00, 0x11, 0x89, // mov a, es:[de] + 0xFC, 0xA1, 0xFF, 0x0E, // call !!0xeffa1 + 0xA5, // incw de + 0x15, // movw ax, de + 0x44, 0x00, 0x00, // cmpw ax, #0 + 0xDF, 0xF3, // bnz $next + 0xEF, 0x04, // br $after_ocd_flag + 0x55, // ocd_flag + // nop + // mov a, es + // inc a + // and a, #0xf + // mov es, a + 0x00, 0x00, 0x00, 0x8E, 0xFD, 0x81, 0x5C, 0x0F, 0x9E, 0xFD, 0x71, 0x00, 0x90, 0x00, + 0xEF, 0xE0 // br $next }; +static uint8_t dumper_g23[] = { + 0x41, 0x00, 0x34, 0x00, 0x00, 0x11, 0x89, 0xef, 0x10, 0xa5, 0x15, 0x44, 0x00, + 0x00, 0xdf, 0xf5, 0x8e, 0xfd, 0x81, 0x5c, 0x0f, 0x9e, 0xfd, 0xef, 0xec, 0x71, + 0x7a, 0xaf, 0x00, 0x9e, 0xad, 0x31, 0xb4, 0xaf, 0xfc, 0x71, 0x3b, 0xaf, 0x71, + 0x7b, 0xaf, 0xef, 0xde +}; + + static uint8_t G1M_payload_1[] = { 0xcb, 0xf8, 0xc0, 0xfe, // movw sp, #0xfea0 0xec, 0xba, 0xff, 0x0e, // br !!0xeffba @@ -166,7 +225,7 @@ static uint8_t G1M_paramtest[] = { }; -void cli_tool78_glitch_dump(void) { +static void cli_tool78_glitch_dump_base(size_t pl_size, const uint8_t* payload) { uint8_t passwd[10] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; uint16_t ver; enum tool78_stat st; @@ -200,8 +259,7 @@ void cli_tool78_glitch_dump(void) { goto deinit_bad; } - st = tool78_ocd_write(&tool78_hw_rl78_uart1, 0xf900, - sizeof(dumper_shellcode), dumper_shellcode); + st = tool78_ocd_write(&tool78_hw_rl78_uart1, 0xf900, pl_size, payload); //printf("write shellcode res 0x%02x\n", st); if (st != 0) { printf("shellcode write failed: %d\n", st); @@ -233,11 +291,20 @@ deinit_bad: tool78_hw_rl78_uart1.deinit(); return; } +void cli_tool78_glitch_dump(void) { + cli_tool78_glitch_dump_base(sizeof(dumper_shellcode), dumper_shellcode); +} +void cli_tool78_glitch_dump_g23(void) { + cli_tool78_glitch_dump_base(sizeof(dumper_g23), dumper_g23); +} -void cli_tool78_glitch_paramsearch(void) { +static void glitch_paramsearch_base(size_t pl_size, const uint8_t* payload) { + zap_gpio_set_en(true); +#if USE_PICOEMP zap_picoemp_init(); +#endif - if (!glitch_init_core1_stuff(true, ZAP_GLITCH_OUT/*GLITCH_OUT_PIN*/)) { + if (!glitch_init_core1_stuff(true, GLITCH_OUT_PIN)) { printf("bad glitcher params!\n"); return; } @@ -250,12 +317,15 @@ void cli_tool78_glitch_paramsearch(void) { bool first = true; restart: +#if USE_PICOEMP zap_picoemp_set_armed(false); +#endif glitch_disarm(); /*busy_wait_ms(40);*/ +#if USE_PICOEMP zap_picoemp_set_armed(true); - while (!zap_picoemp_has_hv()) ; +#endif ver=0; st = tool78_init_ocd(&tool78_hw_rl78_uart1, &ver, passwd); @@ -285,14 +355,17 @@ restart: printf("trampoline write failed: %d\n", st); goto deinit_bad; } - st = tool78_ocd_write(&tool78_hw_rl78_uart1, 0xf900, - sizeof(DATA_test_dbg__paramtest), DATA_test_dbg__paramtest); + st = tool78_ocd_write(&tool78_hw_rl78_uart1, 0xf900, pl_size, payload); //printf("write code res 0x%02x\n", st); if (st != 0) { printf("code write failed: %d\n", st); goto deinit_bad; } +#if USE_PICOEMP + while (!zap_picoemp_has_hv()) ; +#endif + st = tool78_ocd_exec(&tool78_hw_rl78_uart1); //printf("exec res 0x%02x\n", st); if (st != 0) { @@ -370,19 +443,33 @@ restart: } first_=false; - if (!zap_picoemp_has_hv()) { - rr = tool78_hw_rl78_uart1.recv(2, checkbuf, 150*1000); - } else break; + +#if USE_PICOEMP + while (!zap_picoemp_has_hv()) { + rr = tool78_hw_rl78_uart1.recv(2, checkbuf, 150); + if (rr == 2 && (checkbuf[0] != 'H' || checkbuf[1] != 'i')) rr = 0; + if (rr == 2) { + rr = tool78_hw_rl78_uart1.recv(256, checkbuf, 120*1000); + } + } +#endif + glitch_arm(); + rr = tool78_hw_rl78_uart1.recv(2, checkbuf, 150*1000); + glitch_disarm(); } while (true); } deinit_bad: +#if USE_PICOEMP zap_picoemp_set_armed(false); +#endif tool78_hw_rl78_uart1.deinit(); return; do_reset_stuff: +#if USE_PICOEMP zap_picoemp_set_armed(false); +#endif tool78_hw_rl78_uart1.deinit(); // glitch for way too long to power cycle @@ -392,6 +479,13 @@ do_reset_stuff: goto restart; } +void cli_tool78_glitch_paramsearch(void) { + glitch_paramsearch_base(sizeof(DATA_test_dbg__paramtest), DATA_test_dbg__paramtest); +} + +void cli_tool78_glitch_param_g23(void) { + glitch_paramsearch_base(sizeof(DATA_test_dbg__paramtest_g23), DATA_test_dbg__paramtest_g23); +} void cli_tool78_glitch_ocd_dump(void) { if (!glitch_init_core1_stuff(false, GLITCH_OUT_PIN)) { @@ -399,9 +493,9 @@ void cli_tool78_glitch_ocd_dump(void) { return; } - /*gpio_set_function(2, GPIO_FUNC_SIO); - gpio_set_dir(2, GPIO_OUT); - gpio_put(2, false);*/ + gpio_set_function(11, GPIO_FUNC_SIO); + gpio_set_dir(11, GPIO_OUT); + gpio_put(11, false); //gpio_set_function(3, GPIO_FUNC_SIO); //gpio_set_dir(3, GPIO_OUT); @@ -489,7 +583,7 @@ do_reset_stuff: goto restart; success:; - //gpio_put(2, true); + gpio_put(11, true); //busy_wait_ms(5); // (02): read from above (checkbuf) code // 03 06 18 00 df 03 @@ -567,6 +661,253 @@ deinit_bad: return; } + +void cli_tool78_glitch_ocd_dump_g23(void) { + zap_gpio_set_en(true); +#if USE_PICOEMP + zap_picoemp_init(); +#endif + + if (!glitch_init_core1_stuff(false, GLITCH_OUT_PIN)) { + printf("bad glitcher params!\n"); + return; + } + + gpio_set_function(14, GPIO_FUNC_SIO); + gpio_set_dir(14, GPIO_OUT); + //gpio_put(16, true); + + uint8_t passwd[10] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + uint16_t ver; + int st, rr/*, r0, r1, r2*/; + static uint8_t checkbuf[256]; + bool first = true; + bool phase1; + +restart: +#if USE_PICOEMP + zap_picoemp_set_armed(false); +#endif + glitch_disarm(); + +#if USE_PICOEMP + zap_picoemp_set_armed(true); + while (!zap_picoemp_has_hv()) ; +#endif + + tool78_hw_rl78_uart1.flags &= ~tool78_hw_flag_done_reset; + phase1 = true; + ((struct glitch_param_randrange*)glitch_param_cur.length_ns.ud)->max = LENGTH_1; + //trl78_uart1_set_exclusive(true); + //tool78_hw_rl78_uart1.rx_set_stop_bit(false); + //gpio_put(2, false); + /*glitch_disarm(); + busy_wait_ms(40);*/ + + ver=0; + st = tool78_init_ocd(&tool78_hw_rl78_uart1, &ver, passwd); + if (st == 0xc3) { + //printf("aa\n"); + st = 0; + rr = tool78_hw_rl78_uart1.recv(1, (uint8_t*)&st, 120*1000); + //printf("rr=%d\n", rr); + if (rr != 1) { + //gpio_put(11, true); + printf("aaaa\n"); + //printf("glitch len: %lu ns\n", *(volatile uint32_t*)&glitch_param_cur.length_ns.cur); + busy_wait_ms(1000); + goto do_reset_stuff; + } + } + if (first) printf("result: 0x%02x ver=%04x\n", st, ver); + if (st == 0xc1) goto do_reset_stuff; + if (st != 0x10) { + printf("init: expected protect error, got %d\n", st); + goto deinit_bad; + } + busy_wait_ms(16); // leave time to recharge + + // 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; + +glitch_continue: + //tool78_hw_rl78_uart1.rx_set_stop_bit(false); + glitch_arm(); + for (size_t i = 0; i < (phase1 ? 16 : 64); ++i) { +#if USE_PICOEMP + while (!zap_picoemp_has_hv()) { + rr = tool78_hw_rl78_uart1.recv(1, checkbuf, 150); + if (rr > 0) goto welp; + } +#endif + //glitch_trigger_sw_core1(); + glitch_trigger_sw_pio(); + rr = tool78_hw_rl78_uart1.recv(1, checkbuf, 12*1000); + welp: + if (rr != 1) { + busy_wait_ms(1); // leave time to recharge + printf("."); + continue; + } + + /*printf("checkbuf: %d", checkbuf[0]); + printf("\n!!!\n");*/ + tool78_hw_rl78_uart1.flags |= tool78_hw_flag_done_reset; + + glitch_disarm(); + goto success; + } + glitch_disarm(); + + printf(":"); +do_reset_stuff: + tool78_hw_rl78_uart1.deinit(); + + busy_wait_ms(15); + //gpio_put(16, false); + // glitch for way too long to power cycle + /*sio_hw->gpio_set = 1u << GLITCH_OUT_PIN; + sio_hw->gpio_clr = 1u << GLITCH_OUT_PIN;*/ + //busy_wait_ms(15); + //gpio_put(16, true); + //busy_wait_ms(15); + + goto restart; + +success:; + //busy_wait_ms(5); + if (phase1) { + // (02): read from above (checkbuf) code + // 01 XX YY 03 + // ^-- baud rate set response + // ^ XX is some err. code (variable, should be 0x23 but can vary due to glitch), YY is checksum + + //gpio_put(11, true); + rr = tool78_hw_rl78_uart1.recv(4, &databuf[0], 10000); + if (rr != 4) { + printf("wut? rr=%d prev=%02x\n", rr, checkbuf[0]); + goto do_reset_stuff; + } else { + //gpio_put(14, true); + printf("glitch phase1 done: %02x %02x %02x %02x %02x\n", checkbuf[0], + databuf[0], databuf[1], databuf[2], databuf[3]); + printf("glitch len: %lu ns\n", *(volatile uint32_t*)&glitch_param_cur.length_ns.cur); + busy_wait_ms(1); // time to settle + phase1 = false; + ((struct glitch_param_randrange*)glitch_param_cur.length_ns.ud)->max = LENGTH_2; + //gpio_put(14, false); + goto glitch_continue; + } + } else { + // (02): read from above (checkbuf) code + // 03 06 18 00 df 03 + // 00 + gpio_put(14, true); + rr = tool78_hw_rl78_uart1.recv(6, &databuf[0], 10000); + if (rr != 6) { + printf("wut? rr=%d prev=%02x\n", rr, checkbuf[0]); + restart_to_ph1: + phase1 = true; + ((struct glitch_param_randrange*)glitch_param_cur.length_ns.ud)->max = LENGTH_1; + gpio_put(14, false); + goto do_reset_stuff; + } else { + printf("glitch phase2 done: %02x %02x %02x %02x %02x %02x %02x\n", + checkbuf[0], databuf[0], databuf[1], databuf[2], + databuf[3], databuf[4], databuf[5]); + printf("glitch len: %lu ns\n", *(volatile uint32_t*)&glitch_param_cur.length_ns.cur); + busy_wait_ms(1); // time to settle + rr = tool78_hw_rl78_uart1.recv(1, &checkbuf[0], 10000); + if (rr != 1) { + printf("wut? rr=%d no ack null byte\n", rr); + goto restart_to_ph1; + } + printf("got ack!\n"); + } + } + +#if USE_PICOEMP + zap_picoemp_set_armed(false); +#endif + glitch_disarm(); + busy_wait_us_32(500); + gpio_put(14, false); + + ver = 0; + st = tool78_ocd_version(&tool78_hw_rl78_uart1, &ver); + if (st) { + printf("OCD: get version failed: %d\n", st); + goto do_reset_stuff; + } + printf("got ver! %04x\n", ver); + + /*goto do_reset_stuff;*/ + + st = tool78_ocd_connect(&tool78_hw_rl78_uart1, passwd); + if (st != 0xf0 && st != 0xf2) { + printf("OCD: connect failed: %d\n", st); + goto deinit_bad; + } + printf("connect! 0x%02x\n", st); + + // 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(&tool78_hw_rl78_uart1, 0x07e0, + sizeof(exec_jmp_to_ram), exec_jmp_to_ram); + //printf("write trampoline res 0x%02x\n", st); + if (st != 0) { + printf("trampoline write failed: %d\n", st); + goto deinit_bad; + } + st = tool78_ocd_write(&tool78_hw_rl78_uart1, 0xf900, + sizeof(dumper_g23), dumper_g23); + //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(&tool78_hw_rl78_uart1); + //printf("exec res 0x%02x\n", st); + if (st != 0) { + printf("exec failed: %d\n", st); + goto deinit_bad; + } + + for (size_t iii = 0; iii < DUMP_SIZE + DUMP_OFFSET; ++iii) { + // wait for completion + size_t off = (iii < DUMP_OFFSET) ? 0 : (iii - DUMP_OFFSET); + rr = tool78_hw_rl78_uart1.recv(1, &databuf[off], 120*1000*1000); + if (rr != 1) { + printf("exec code: no response :/ (%d)\n", rr); + goto deinit_bad; + } + } + + for (size_t iii = 0; iii < DUMP_SIZE; ++iii) { + printf("0x%02x%s", databuf[iii], ((iii & 0xf) == 0xf) ? "\n" : " "); + } + + printf("\ndone!\n"); + +deinit_bad: + tool78_hw_rl78_uart1.deinit(); + return; +} + /*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, diff --git a/src/cli/rl78.c b/src/cli/rl78.c index 1d16b51..604ea99 100644 --- a/src/cli/rl78.c +++ b/src/cli/rl78.c @@ -38,6 +38,17 @@ static uint8_t G1M_test_2[] = { 0xd7, // ret }; +static uint8_t G23_test[19] = { + 0x51, 0x61, // mov a, #'a' + 0x71, 0x7a, 0xaf, // set1 ASIM.7 + 0x00, // nop + 0x9e, 0xad, // mov TXS, a + 0x31, 0xb4, 0xaf, 0xfc, // bf ASIM.3, $. + 0x71, 0x3b, 0xaf, // clr1 ASIM.3 + 0x71, 0x7b, 0xaf, // clr1 ASIM.7 + 0xd7 // ret +}; + //static uint8_t DATA_test_dbg[7/*85*/] = { // /*0xe0, 0x07, 0x52,*/ 0x51, 0x61, 0xfc, 0xa1, 0xff, 0x0e, @@ -178,8 +189,13 @@ void cli_tool78_ocdtest(void) { // 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(&tool78_hw_rl78_uart1, 0x07e0, - sizeof(shellcode_test), shellcode_test); + if (ver < 0x500) { + st = tool78_ocd_write(&tool78_hw_rl78_uart1, 0x07e0, + sizeof(shellcode_test), shellcode_test); + } else { + st = tool78_ocd_write(&tool78_hw_rl78_uart1, 0x07e0, + sizeof(G23_test), G23_test); + } //printf("write shellcode res 0x%02x\n", st); if (st != 0) { printf("shellcode write failed: %d\n", st); @@ -193,6 +209,21 @@ void cli_tool78_ocdtest(void) { goto deinit_bad; } + // wait for completion + rr = tool78_hw_rl78_uart1.recv(1, checkbuf, 120*1000*1000); + if (rr != 1) { + printf("exec code: no response :/ (%d)\n", rr); + goto deinit_bad; + } + printf("result: '%c' (0x%02x)\n", checkbuf[0], checkbuf[0]); + + st = tool78_ocd_exec(&tool78_hw_rl78_uart1); + //printf("exec res 0x%02x\n", st); + if (st != 0) { + printf("exec failed: %d\n", st); + goto deinit_bad; + } + // wait for completion rr = tool78_hw_rl78_uart1.recv(1, checkbuf, 120*1000*1000); if (rr != 1) { diff --git a/src/glitch/glitch.c b/src/glitch/glitch.c index 6f0a650..9e10773 100644 --- a/src/glitch/glitch.c +++ b/src/glitch/glitch.c @@ -127,7 +127,7 @@ static void CORE1_FUNC(glitch_core1_thread_core1_fifoirq)(void) { CORE1_DO_GLITCH(); multicore_fifo_drain(); multicore_fifo_clear_irq(); - gpio_put(25, true); + //gpio_put(25, true); continue_: irq_set_enabled(irq, true); } @@ -151,6 +151,7 @@ static void CORE1_FUNC(glitch_core1_thread_core1_gpio)(void) { CORE1_PRE_CALC(); __WFI(); + //while (!(sio_hw->gpio_in & (1u<intr[gpio>>3] = event << 4*(gpio&7); // acknowledge irq bool arm = *(volatile bool*)¶m_cur.armed; if (!arm) continue; @@ -166,6 +167,7 @@ static void CORE1_FUNC(glitch_core1_thread_core1_gpio)(void) { sio_hw->gpio_clr = iom; cont: irq_set_enabled(irq, true); + //while ((sio_hw->gpio_in & (1u<>2, len>>2); trigctl_wait_glitch_irq(trigctl_pio, trigctl_sm, true); - trigctl_ack_glitch_irq(trigctl_pio, trigctl_sm); - //gpio_put(25, true); //sio_hw->gpio_togl = 1u<<25; + trigctl_ack_glitch_irq(trigctl_pio, trigctl_sm); } } diff --git a/src/tool78/tool78_cmds.c b/src/tool78/tool78_cmds.c index 6abe39e..bd7e3c2 100644 --- a/src/tool78/tool78_cmds.c +++ b/src/tool78/tool78_cmds.c @@ -252,7 +252,7 @@ inline static enum tool78_stat tool78_data_recv(struct tool78_hw* hw, /*#define tool78_wait_status(hw, l, timeout_us, ...) \ tool78_wait_status__impl(hw, l, timeout_us, __VA_OPT__(1 ? __VA_ARGS__ : ) -1) \ */ -static enum tool78_stat tool78_wait_status/*__impl*/(struct tool78_hw* hw, int l, int timeout_us/*, int minl*/) { +static enum tool78_stat tool78_wait_status__impl(struct tool78_hw* hw, int l, int timeout_us/*, int minl*/, const char* fnname, int line) { /*if (hw->target == tool78k0_spi && timeout_us >= 0) { busy_wait_us_32(timeout_us); timeout_us *= 2; @@ -289,9 +289,10 @@ static enum tool78_stat tool78_wait_status/*__impl*/(struct tool78_hw* hw, int l busy_wait_us_32(timeout_us/64); } - printf("wait t/o\n"); + printf("wait t/o: %s:%d\n", fnname, line); return tool78_stat_timeout_error; } +#define tool78_wait_status(hw, l, to) tool78_wait_status__impl(hw, l, to, __func__, __LINE__); // ---- @@ -1115,7 +1116,8 @@ int tool78_ocd_version(struct tool78_hw* hw, uint16_t* ver) { return -1; } - *ver = bytes[0] | ((uint16_t)bytes[1] << 8); + // BCD, so big-endian + *ver = bytes[1] | ((uint16_t)bytes[0] << 8); return 0; } diff --git a/src/tool78/tool78_defs.h b/src/tool78/tool78_defs.h index c1363ea..73506c4 100644 --- a/src/tool78/tool78_defs.h +++ b/src/tool78/tool78_defs.h @@ -5,6 +5,10 @@ #include #include +// NOTE: +// * RL78/x1y flash block size: 0x400 +// * RL78/x2y flash block size: 0x800 + enum tool78_target { tool78k0_uart2 = 0x12, tool78k0_spi = 0x13, @@ -44,7 +48,8 @@ enum tool78_entry { // TOOL0 initial byte values tool78_entry_rl78_uart1 = 0x3a, tool78_entry_rl78_uart2 = 0x00, - tool78_entry_rl78_ocd = 0xc5 + tool78_entry_rl78_ocd = 0xc5, + tool78_entry_rl78_ocd2 = 0xca, // 2-wire OCD (RL78/G23 only) }; // TODO: initial baudrates? 9600 for 78k, 115.2k for RL78 @@ -141,6 +146,7 @@ enum tool78ocd_cmd { // execute code at 0xf07e0 (TODO: verify addr across versions) tool78ocd_cmd_exec = 0x94, tool78ocd_cmd_exit_reti = 0x95, // TODO: what is this? + // TODO: 96 too? tool78ocd_cmd_exit_ram = 0x97, // TODO: what is this? tool78ocd_cmdg10_connect = 0x55, diff --git a/test/rl78/test.S b/test/rl78/test.S deleted file mode 100644 index eb7651e..0000000 --- a/test/rl78/test.S +++ /dev/null @@ -1,135 +0,0 @@ - -/*#include "romhdr.S"*/ -#include "hw.S" - -.global _start -_start: - ;mov a, #'a' - ;call !!0xeffa1 - ;ret - -; call !hw_init - -;1: call !glitch_mainloop -; br $1b - -;1: br $1b - -hw_init: - di - - clrb !CRC0CTL - clrb !IAWCTL - ;CRC0CTL = 0 ; f02f0 - ;IAWCTL = 0 ; f0078 - - ; CSC=fffa1 - ; CKC=fffa4 - ;CMC = 0 ; 0xfffa0 - ;MSTOP = 1 ; CSC.7 - ;MCM0 = 0 ; CKC.4 - ;XTSTOP = 0 ; CSC.6 - ;OSMC = 0 ; f00f3 - ;CSS = 0 ; CKC.6 ;! - set1 CKC.6 - ;HIOSTOP = 0 ; CSC.0 - - mov !ADPC, #1 - ;ADPC = 1 ; f0076 - mov PM2, #0 - - clrb !PMC2 - clrb !PIOR0 - clrb !PIOR1 - clrb !PIOR2 - clrb !PIOR3 - - mov P2, #0 -; ret - - /* DUMPS EVERYTHING */ - - - /* LONG WAITCODE THAT DOESNT DO ANYTHING */ - -/* mov c, #0xff - mov b, #0xff - -1: dec c - bnz $1b - mov c, #0xff - dec b - bnz $1b - xor P2, #0xff - - br $1b*/ - - /* GLITCH TESTING CODE */ - - - /* TODO: how many segments do we need? */ - mov es, #0 - call !dump_segment - -1: br $1b - -dump_segment: - movw hl, #0 -1: mov a, es:[hl] - push hl - call !!tool_tx - pop hl - incw hl - movw ax, hl - cmpw ax, #0 - bnz $1b - mov es, #0xf - ret - -/* -glitch_mainloop: - mov P2, #0xff - - movw ax, #0xfa00 - movw hl, ax - - mov c, #0 -2: mov b, #0xff - mov a, #0 -1: inc a - dec b - bnz $1b - dec c - mov [hl+c], a - bnz $2b - - mov P2, #0 - - ; wait a bit - mov c, #0x18 -4: mov b, #0xff -5: dec b - bnz $5b - dec c - bnz $4b - - mov a, #'H' - call !!tool_tx - mov a, #'i' - call !!tool_tx - - mov x, #0xaa - mov c, #0 -3: dec c - mov a, [hl+c] - xor a, x - call !!tool_tx - cmp0 c - bnz $3b - - br $glitch_mainloop - - ;ret - -;data: -*/ diff --git a/test/rl78/test.S b/test/rl78/test.S new file mode 120000 index 0000000..c7e830b --- /dev/null +++ b/test/rl78/test.S @@ -0,0 +1 @@ +test_g13_param.S \ No newline at end of file diff --git a/test/rl78/test_g13_param.S b/test/rl78/test_g13_param.S new file mode 100644 index 0000000..f3ee03d --- /dev/null +++ b/test/rl78/test_g13_param.S @@ -0,0 +1,91 @@ + +/*#include "romhdr.S"*/ +#include "hw.S" + +.global _start +_start: + ;mov a, #'a' + ;call !!0xeffa1 + ;ret + + di + + clrb !CRC0CTL + clrb !IAWCTL + ;CRC0CTL = 0 ; f02f0 + ;IAWCTL = 0 ; f0078 + + ; CSC=fffa1 + ; CKC=fffa4 + ;CMC = 0 ; 0xfffa0 + ;MSTOP = 1 ; CSC.7 + ;MCM0 = 0 ; CKC.4 + ;XTSTOP = 0 ; CSC.6 + ;OSMC = 0 ; f00f3 + ;CSS = 0 ; CKC.6 ;! + set1 CKC.6 + ;HIOSTOP = 0 ; CSC.0 + + mov !ADPC, #1 + ;ADPC = 1 ; f0076 + mov PM2, #0 + + clrb !PMC2 + clrb !PIOR0 + clrb !PIOR1 + clrb !PIOR2 + clrb !PIOR3 + + mov P2, #0 + + +glitch_mainloop: + mov P2, #0xff + + movw ax, #0xfa00 + movw hl, ax + + mov c, #0 +2: mov b, #0xff + mov a, #0 +1: inc a + dec b + bnz $1b + dec c + mov [hl+c], a + bnz $2b + + mov P2, #0 + + ; wait a bit + mov c, #0x18 +4: mov b, #0xff +5: dec b + bnz $5b + dec c + bnz $4b + + mov a, #'H' + call !!tool_tx + mov a, #'i' + call !!tool_tx + + mov x, #0xaa + mov c, #0 +3: dec c + mov a, [hl+c] + xor a, x + call !!tool_tx + cmp0 c + bnz $3b + + ; wait a bit + mov c, #0x30 +4: mov b, #0xff +5: dec b + bnz $5b + dec c + bnz $4b + + br $glitch_mainloop + diff --git a/test/rl78/test_g23_ocd.S b/test/rl78/test_g23_ocd.S new file mode 100644 index 0000000..9516e5a --- /dev/null +++ b/test/rl78/test_g23_ocd.S @@ -0,0 +1,41 @@ + +/*#include "romhdr.S"*/ +#include "hw.S" + +#define REG_ASIM 0xfffaf +#define REG_TXS 0xfffad + +.global _start +_start: +/* ROM starts at 0xee000 on G23 */ + mov es, #0 + movw de, #0 + + /*mov a, es:[de] + + mov a, #'a'*/ + +next: + mov a, es:[de] + br $tool_tx_fake +return_bleh: + incw de + movw ax, de + cmpw ax, #0 + bnz $next + mov a, es + inc a + and a, #0xf + mov es, a + br $next + +tool_tx_fake: + set1 REG_ASIM.7 + nop + mov REG_TXS, a +wait_sent: + bf REG_ASIM.3, $wait_sent + clr1 REG_ASIM.3 + clr1 REG_ASIM.7 + br $return_bleh + /*ret*/ diff --git a/test/rl78/test_g23_param.S b/test/rl78/test_g23_param.S new file mode 100644 index 0000000..cbd3d59 --- /dev/null +++ b/test/rl78/test_g23_param.S @@ -0,0 +1,106 @@ + +/*#include "romhdr.S"*/ +#include "hw.S" + +#define REG_ASIM 0xfffaf +#define REG_TXS 0xfffad + +#define tool_tx_g23 0xeeac0 + +/*#define TX_FUNC !!tool_tx_g23*/ +#define TX_FUNC $!my_tool_tx + +.global _start +_start: + ;mov a, #'a' + ;call !!0xeffa1 + ;ret + + di + + clrb !CRC0CTL + clrb !IAWCTL + ;CRC0CTL = 0 ; f02f0 + ;IAWCTL = 0 ; f0078 + + ; CSC=fffa1 + ; CKC=fffa4 + ;CMC = 0 ; 0xfffa0 + ;MSTOP = 1 ; CSC.7 + ;MCM0 = 0 ; CKC.4 + ;XTSTOP = 0 ; CSC.6 + ;OSMC = 0 ; f00f3 + ;CSS = 0 ; CKC.6 ;! + ;set1 CKC.6 + ;HIOSTOP = 0 ; CSC.0 + +; mov !ADPC, #1 + ;ADPC = 1 ; f0076 + mov PM2, #0 + + clrb !PMC2 + clrb !PIOR0 + clrb !PIOR1 + clrb !PIOR2 + clrb !PIOR3 + + clrb P2 + + movw sp, #0xfe00 + +glitch_mainloop: + mov P2, #0xff + mov P2, #0xff + + movw ax, #0xc000 + movw ax, #0xc000 + movw hl, ax + movw hl, ax + + mov c, #0 +2: mov b, #0xff + mov a, #0 +1: inc a + dec b + bnz $1b + dec c + mov [hl+c], a + bnz $2b + + clrb P2 + clrb P2 + + ; wait a bit + mov c, #0x18 +4: mov b, #0xff +5: dec b + bnz $5b + dec c + bnz $4b + + mov a, #'H' + call TX_FUNC + mov a, #'i' + call TX_FUNC + + mov x, #0xaa + mov c, #0 +3: dec c + mov a, [hl+c] + xor a, x + call TX_FUNC + cmp0 c + bnz $3b + + br $glitch_mainloop + +my_tool_tx: + set1 REG_ASIM.7 + nop + mov REG_TXS, a +wait_sent: + bf REG_ASIM.3, $wait_sent + clr1 REG_ASIM.3 + clr1 REG_ASIM.7 + ret + diff --git a/test/rl78/test_old.S b/test/rl78/test_old.S new file mode 100644 index 0000000..eb7651e --- /dev/null +++ b/test/rl78/test_old.S @@ -0,0 +1,135 @@ + +/*#include "romhdr.S"*/ +#include "hw.S" + +.global _start +_start: + ;mov a, #'a' + ;call !!0xeffa1 + ;ret + +; call !hw_init + +;1: call !glitch_mainloop +; br $1b + +;1: br $1b + +hw_init: + di + + clrb !CRC0CTL + clrb !IAWCTL + ;CRC0CTL = 0 ; f02f0 + ;IAWCTL = 0 ; f0078 + + ; CSC=fffa1 + ; CKC=fffa4 + ;CMC = 0 ; 0xfffa0 + ;MSTOP = 1 ; CSC.7 + ;MCM0 = 0 ; CKC.4 + ;XTSTOP = 0 ; CSC.6 + ;OSMC = 0 ; f00f3 + ;CSS = 0 ; CKC.6 ;! + set1 CKC.6 + ;HIOSTOP = 0 ; CSC.0 + + mov !ADPC, #1 + ;ADPC = 1 ; f0076 + mov PM2, #0 + + clrb !PMC2 + clrb !PIOR0 + clrb !PIOR1 + clrb !PIOR2 + clrb !PIOR3 + + mov P2, #0 +; ret + + /* DUMPS EVERYTHING */ + + + /* LONG WAITCODE THAT DOESNT DO ANYTHING */ + +/* mov c, #0xff + mov b, #0xff + +1: dec c + bnz $1b + mov c, #0xff + dec b + bnz $1b + xor P2, #0xff + + br $1b*/ + + /* GLITCH TESTING CODE */ + + + /* TODO: how many segments do we need? */ + mov es, #0 + call !dump_segment + +1: br $1b + +dump_segment: + movw hl, #0 +1: mov a, es:[hl] + push hl + call !!tool_tx + pop hl + incw hl + movw ax, hl + cmpw ax, #0 + bnz $1b + mov es, #0xf + ret + +/* +glitch_mainloop: + mov P2, #0xff + + movw ax, #0xfa00 + movw hl, ax + + mov c, #0 +2: mov b, #0xff + mov a, #0 +1: inc a + dec b + bnz $1b + dec c + mov [hl+c], a + bnz $2b + + mov P2, #0 + + ; wait a bit + mov c, #0x18 +4: mov b, #0xff +5: dec b + bnz $5b + dec c + bnz $4b + + mov a, #'H' + call !!tool_tx + mov a, #'i' + call !!tool_tx + + mov x, #0xaa + mov c, #0 +3: dec c + mov a, [hl+c] + xor a, x + call !!tool_tx + cmp0 c + bnz $3b + + br $glitch_mainloop + + ;ret + +;data: +*/