rl78/g23 probe and glitching routines

This commit is contained in:
Triss 2022-07-18 11:38:06 +02:00
parent 8fab6d984c
commit 8820a9b40e
12 changed files with 801 additions and 174 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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<<gpio))) ;
iobank0_hw->intr[gpio>>3] = event << 4*(gpio&7); // acknowledge irq
bool arm = *(volatile bool*)&param_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<<gpio))) ;
}
}
__attribute__((__noreturn__))
@ -178,6 +180,7 @@ static void CORE1_FUNC(glitch_core1_thread_pio)(void) {
irq_set_enabled(irq, true);
while (true) {
//gpio_put(25, gpio_get(10));
CORE1_PRE_CALC();
(void)iom;
param_cur.offset_ns.cur = off;
@ -185,9 +188,8 @@ static void CORE1_FUNC(glitch_core1_thread_pio)(void) {
trigctl_push_off_len(trigctl_pio, trigctl_sm, off>>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);
}
}

View File

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

View File

@ -5,6 +5,10 @@
#include <stddef.h>
#include <stdint.h>
// 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,

View File

@ -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:
*/

1
test/rl78/test.S Symbolic link
View File

@ -0,0 +1 @@
test_g13_param.S

View File

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

41
test/rl78/test_g23_ocd.S Normal file
View File

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

106
test/rl78/test_g23_param.S Normal file
View File

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

135
test/rl78/test_old.S Normal file
View File

@ -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:
*/