rl78/g23 probe and glitching routines
This commit is contained in:
parent
8fab6d984c
commit
8820a9b40e
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
#define TRIGGER_IN_PIN ZAP_TRIG_IN
|
#define TRIGGER_IN_PIN ZAP_TRIG_IN
|
||||||
// use CROWBAR_1 / CROWBAR_2 / GLITCH_OUT to select glitching method
|
// 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_PIO BREADBOARD_SBW_PIO
|
||||||
#define PINOUT_SBW_TCK (ZAP_GPIO_BASE+0)
|
#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_FLMD0 (ZAP_GPIO_BASE+1)
|
||||||
#define PINOUT_TOOL78_78K0R_TOOL0 (ZAP_GPIO_BASE+2)
|
#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_TX (ZAP_GPIO_BASE+2)
|
||||||
#define PINOUT_TOOL78_RL78_RX (ZAP_GPIO_BASE+3)
|
#define PINOUT_TOOL78_RL78_RX (ZAP_GPIO_BASE+3)
|
||||||
|
|
||||||
|
|
|
@ -33,8 +33,11 @@ void cli_tool78_g10_prototest(void);
|
||||||
void cli_tool78_g10_ocdtest(void);
|
void cli_tool78_g10_ocdtest(void);
|
||||||
|
|
||||||
void cli_tool78_glitch_dump(void);
|
void cli_tool78_glitch_dump(void);
|
||||||
|
void cli_tool78_glitch_dump_g23(void);
|
||||||
void cli_tool78_glitch_paramsearch(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(void);
|
||||||
|
void cli_tool78_glitch_ocd_dump_g23(void);
|
||||||
void cli_tool78_glitch_param_g10(void);
|
void cli_tool78_glitch_param_g10(void);
|
||||||
void cli_tool78_glitch_ocd_g10(void);
|
void cli_tool78_glitch_ocd_g10(void);
|
||||||
|
|
||||||
|
@ -85,8 +88,11 @@ static struct cli_cmd cmds[] = {
|
||||||
{ "rl10ocd", cli_tool78_g10_ocdtest },
|
{ "rl10ocd", cli_tool78_g10_ocdtest },
|
||||||
|
|
||||||
{ "g78dump", cli_tool78_glitch_dump },
|
{ "g78dump", cli_tool78_glitch_dump },
|
||||||
|
{ "g23dump", cli_tool78_glitch_dump_g23 },
|
||||||
{ "g78param", cli_tool78_glitch_paramsearch },
|
{ "g78param", cli_tool78_glitch_paramsearch },
|
||||||
|
{ "g23param", cli_tool78_glitch_param_g23 },
|
||||||
{ "g78ocd", cli_tool78_glitch_ocd_dump },
|
{ "g78ocd", cli_tool78_glitch_ocd_dump },
|
||||||
|
{ "g23ocd", cli_tool78_glitch_ocd_dump_g23 },
|
||||||
{ "g10param", cli_tool78_glitch_param_g10 },
|
{ "g10param", cli_tool78_glitch_param_g10 },
|
||||||
{ "g10ocd", cli_tool78_glitch_ocd_g10 },
|
{ "g10ocd", cli_tool78_glitch_ocd_g10 },
|
||||||
|
|
||||||
|
|
|
@ -16,13 +16,19 @@
|
||||||
#include "glitch.h"
|
#include "glitch.h"
|
||||||
|
|
||||||
void cli_tool78_glitch_dump(void);
|
void cli_tool78_glitch_dump(void);
|
||||||
|
void cli_tool78_glitch_dump_g23(void);
|
||||||
void cli_tool78_glitch_paramsearch(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(void);
|
||||||
|
void cli_tool78_glitch_ocd_dump_g23(void);
|
||||||
void cli_tool78_glitch_param_g10(void);
|
void cli_tool78_glitch_param_g10(void);
|
||||||
void cli_tool78_glitch_ocd_g10(void);
|
void cli_tool78_glitch_ocd_g10(void);
|
||||||
|
|
||||||
#define DUMP_OFFSET 0xef000
|
#define USE_PICOEMP 0
|
||||||
#define DUMP_SIZE 4096/*65536*/
|
#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
|
// test with decoupling caps: length in 20..500(..1500) -> ok
|
||||||
// testing on ocd lock: length: 5..35
|
// 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 uint8_t databuf[DUMP_SIZE];
|
||||||
static struct glitch_param_randrange offset;
|
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;
|
//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) {
|
static bool glitch_init_core1_stuff(bool exttrig, uint glitchpin) {
|
||||||
offset.min = 10*1000;
|
offset.min = 10*1000;
|
||||||
offset.max = 35433*1000;
|
offset.max = 35433*1000/25;
|
||||||
length.min = 100;
|
length.min = 25;//100;
|
||||||
length.max = /*10*50*/26*1000;
|
length.max = /*10*50*/LENGTH_1;
|
||||||
//length.value = 5*1000; // 5 us
|
//length.value = 5*1000; // 5 us
|
||||||
|
#if LEN_USE_ADC
|
||||||
#if PINOUT_USE_DRAGONZAP
|
#if PINOUT_USE_DRAGONZAP
|
||||||
//length.adc_index = 0;//999;
|
length.adc_index = 0;//999;
|
||||||
#else
|
#else
|
||||||
//length.adc_index = 999;
|
length.adc_index = 999;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
glitch_param_randrange_init(&offset);
|
glitch_param_randrange_init(&offset);
|
||||||
//glitch_param_const_init(&length);
|
//glitch_param_const_init(&length);
|
||||||
|
#if LEN_USE_ADC
|
||||||
|
glitch_param_adc_init(&length);
|
||||||
|
#else
|
||||||
glitch_param_randrange_init(&length);
|
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!
|
// 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){
|
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){
|
gparam.length_ns = (struct glitch_param){
|
||||||
.ud = &length,
|
.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);
|
gparam.trigger_in_pin = exttrig ? TRIGGER_IN_PIN/*7*/ : (-1);
|
||||||
return glitch_ready(&gparam);
|
return glitch_ready(&gparam);
|
||||||
|
@ -137,13 +159,50 @@ static uint8_t DATA_test_dbg__paramtest[102] = {
|
||||||
0x0e, 0xd2, 0xdf, 0xf4, 0xef, 0xbf
|
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] = {
|
static uint8_t dumper_shellcode[0x26] = {
|
||||||
//0xe0, 0x07, 0x26, // 0xF07E0 location, 0x26 length of packet
|
//0xe0, 0x07, 0x26, // 0xF07E0 location, 0x26 length of packet
|
||||||
0x41, 0x00, 0x34, 0x00, 0x00, 0x00, 0x11, 0x89, 0xFC, 0xA1, 0xFF, 0x0E, 0xA5,
|
0x41, 0x00, // mov es, #0
|
||||||
0x15, 0x44, 0x00, 0x00, 0xDF, 0xF3, 0xEF, 0x04, 0x55, 0x00, 0x00, 0x00, 0x8E,
|
0x34, 0x00, 0x00, // movw de, #0
|
||||||
0xFD, 0x81, 0x5C, 0x0F, 0x9E, 0xFD, 0x71, 0x00, 0x90, 0x00, 0xEF, 0xE0
|
// 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[] = {
|
static uint8_t G1M_payload_1[] = {
|
||||||
0xcb, 0xf8, 0xc0, 0xfe, // movw sp, #0xfea0
|
0xcb, 0xf8, 0xc0, 0xfe, // movw sp, #0xfea0
|
||||||
0xec, 0xba, 0xff, 0x0e, // br !!0xeffba
|
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};
|
uint8_t passwd[10] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||||
uint16_t ver;
|
uint16_t ver;
|
||||||
enum tool78_stat st;
|
enum tool78_stat st;
|
||||||
|
@ -200,8 +259,7 @@ void cli_tool78_glitch_dump(void) {
|
||||||
goto deinit_bad;
|
goto deinit_bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
st = tool78_ocd_write(&tool78_hw_rl78_uart1, 0xf900,
|
st = tool78_ocd_write(&tool78_hw_rl78_uart1, 0xf900, pl_size, payload);
|
||||||
sizeof(dumper_shellcode), dumper_shellcode);
|
|
||||||
//printf("write shellcode res 0x%02x\n", st);
|
//printf("write shellcode res 0x%02x\n", st);
|
||||||
if (st != 0) {
|
if (st != 0) {
|
||||||
printf("shellcode write failed: %d\n", st);
|
printf("shellcode write failed: %d\n", st);
|
||||||
|
@ -233,11 +291,20 @@ deinit_bad:
|
||||||
tool78_hw_rl78_uart1.deinit();
|
tool78_hw_rl78_uart1.deinit();
|
||||||
return;
|
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();
|
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");
|
printf("bad glitcher params!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -250,12 +317,15 @@ void cli_tool78_glitch_paramsearch(void) {
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
|
||||||
restart:
|
restart:
|
||||||
|
#if USE_PICOEMP
|
||||||
zap_picoemp_set_armed(false);
|
zap_picoemp_set_armed(false);
|
||||||
|
#endif
|
||||||
glitch_disarm();
|
glitch_disarm();
|
||||||
/*busy_wait_ms(40);*/
|
/*busy_wait_ms(40);*/
|
||||||
|
|
||||||
|
#if USE_PICOEMP
|
||||||
zap_picoemp_set_armed(true);
|
zap_picoemp_set_armed(true);
|
||||||
while (!zap_picoemp_has_hv()) ;
|
#endif
|
||||||
|
|
||||||
ver=0;
|
ver=0;
|
||||||
st = tool78_init_ocd(&tool78_hw_rl78_uart1, &ver, passwd);
|
st = tool78_init_ocd(&tool78_hw_rl78_uart1, &ver, passwd);
|
||||||
|
@ -285,14 +355,17 @@ restart:
|
||||||
printf("trampoline write failed: %d\n", st);
|
printf("trampoline write failed: %d\n", st);
|
||||||
goto deinit_bad;
|
goto deinit_bad;
|
||||||
}
|
}
|
||||||
st = tool78_ocd_write(&tool78_hw_rl78_uart1, 0xf900,
|
st = tool78_ocd_write(&tool78_hw_rl78_uart1, 0xf900, pl_size, payload);
|
||||||
sizeof(DATA_test_dbg__paramtest), DATA_test_dbg__paramtest);
|
|
||||||
//printf("write code res 0x%02x\n", st);
|
//printf("write code res 0x%02x\n", st);
|
||||||
if (st != 0) {
|
if (st != 0) {
|
||||||
printf("code write failed: %d\n", st);
|
printf("code write failed: %d\n", st);
|
||||||
goto deinit_bad;
|
goto deinit_bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USE_PICOEMP
|
||||||
|
while (!zap_picoemp_has_hv()) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
st = tool78_ocd_exec(&tool78_hw_rl78_uart1);
|
st = tool78_ocd_exec(&tool78_hw_rl78_uart1);
|
||||||
//printf("exec res 0x%02x\n", st);
|
//printf("exec res 0x%02x\n", st);
|
||||||
if (st != 0) {
|
if (st != 0) {
|
||||||
|
@ -370,19 +443,33 @@ restart:
|
||||||
}
|
}
|
||||||
|
|
||||||
first_=false;
|
first_=false;
|
||||||
if (!zap_picoemp_has_hv()) {
|
|
||||||
|
#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);
|
rr = tool78_hw_rl78_uart1.recv(2, checkbuf, 150*1000);
|
||||||
} else break;
|
glitch_disarm();
|
||||||
} while (true);
|
} while (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit_bad:
|
deinit_bad:
|
||||||
|
#if USE_PICOEMP
|
||||||
zap_picoemp_set_armed(false);
|
zap_picoemp_set_armed(false);
|
||||||
|
#endif
|
||||||
tool78_hw_rl78_uart1.deinit();
|
tool78_hw_rl78_uart1.deinit();
|
||||||
return;
|
return;
|
||||||
|
|
||||||
do_reset_stuff:
|
do_reset_stuff:
|
||||||
|
#if USE_PICOEMP
|
||||||
zap_picoemp_set_armed(false);
|
zap_picoemp_set_armed(false);
|
||||||
|
#endif
|
||||||
tool78_hw_rl78_uart1.deinit();
|
tool78_hw_rl78_uart1.deinit();
|
||||||
|
|
||||||
// glitch for way too long to power cycle
|
// glitch for way too long to power cycle
|
||||||
|
@ -392,6 +479,13 @@ do_reset_stuff:
|
||||||
|
|
||||||
goto restart;
|
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) {
|
void cli_tool78_glitch_ocd_dump(void) {
|
||||||
if (!glitch_init_core1_stuff(false, GLITCH_OUT_PIN)) {
|
if (!glitch_init_core1_stuff(false, GLITCH_OUT_PIN)) {
|
||||||
|
@ -399,9 +493,9 @@ void cli_tool78_glitch_ocd_dump(void) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*gpio_set_function(2, GPIO_FUNC_SIO);
|
gpio_set_function(11, GPIO_FUNC_SIO);
|
||||||
gpio_set_dir(2, GPIO_OUT);
|
gpio_set_dir(11, GPIO_OUT);
|
||||||
gpio_put(2, false);*/
|
gpio_put(11, false);
|
||||||
|
|
||||||
//gpio_set_function(3, GPIO_FUNC_SIO);
|
//gpio_set_function(3, GPIO_FUNC_SIO);
|
||||||
//gpio_set_dir(3, GPIO_OUT);
|
//gpio_set_dir(3, GPIO_OUT);
|
||||||
|
@ -489,7 +583,7 @@ do_reset_stuff:
|
||||||
goto restart;
|
goto restart;
|
||||||
|
|
||||||
success:;
|
success:;
|
||||||
//gpio_put(2, true);
|
gpio_put(11, true);
|
||||||
//busy_wait_ms(5);
|
//busy_wait_ms(5);
|
||||||
// (02): read from above (checkbuf) code
|
// (02): read from above (checkbuf) code
|
||||||
// 03 06 18 00 df 03
|
// 03 06 18 00 df 03
|
||||||
|
@ -567,6 +661,253 @@ deinit_bad:
|
||||||
return;
|
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] = {
|
/*static uint8_t DATA_G1M_paramtest[47] = {
|
||||||
0xcf, 0x77, 0x00, 0x00, 0xce, 0x00, 0x00, 0xcf, 0x30, 0x00, 0x00, 0xcf, 0x50,
|
0xcf, 0x77, 0x00, 0x00, 0xce, 0x00, 0x00, 0xcf, 0x30, 0x00, 0x00, 0xcf, 0x50,
|
||||||
0x00, 0x00, 0xcf, 0x60, 0x00, 0x7f, 0xcf, 0x20, 0xff, 0x00, 0xcf, 0xf0, 0x00,
|
0x00, 0x00, 0xcf, 0x60, 0x00, 0x7f, 0xcf, 0x20, 0xff, 0x00, 0xcf, 0xf0, 0x00,
|
||||||
|
|
|
@ -38,6 +38,17 @@ static uint8_t G1M_test_2[] = {
|
||||||
0xd7, // ret
|
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*/] = {
|
//static uint8_t DATA_test_dbg[7/*85*/] = {
|
||||||
// /*0xe0, 0x07, 0x52,*/ 0x51, 0x61, 0xfc, 0xa1, 0xff, 0x0e,
|
// /*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,
|
// can't write too much at 0xf07e0 as 0xf0800 and up contains OCD state,
|
||||||
// overwrite this and suddenly the OCD system resets itself
|
// overwrite this and suddenly the OCD system resets itself
|
||||||
|
if (ver < 0x500) {
|
||||||
st = tool78_ocd_write(&tool78_hw_rl78_uart1, 0x07e0,
|
st = tool78_ocd_write(&tool78_hw_rl78_uart1, 0x07e0,
|
||||||
sizeof(shellcode_test), shellcode_test);
|
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);
|
//printf("write shellcode res 0x%02x\n", st);
|
||||||
if (st != 0) {
|
if (st != 0) {
|
||||||
printf("shellcode write failed: %d\n", st);
|
printf("shellcode write failed: %d\n", st);
|
||||||
|
@ -193,6 +209,21 @@ void cli_tool78_ocdtest(void) {
|
||||||
goto deinit_bad;
|
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
|
// wait for completion
|
||||||
rr = tool78_hw_rl78_uart1.recv(1, checkbuf, 120*1000*1000);
|
rr = tool78_hw_rl78_uart1.recv(1, checkbuf, 120*1000*1000);
|
||||||
if (rr != 1) {
|
if (rr != 1) {
|
||||||
|
|
|
@ -127,7 +127,7 @@ static void CORE1_FUNC(glitch_core1_thread_core1_fifoirq)(void) {
|
||||||
CORE1_DO_GLITCH();
|
CORE1_DO_GLITCH();
|
||||||
multicore_fifo_drain();
|
multicore_fifo_drain();
|
||||||
multicore_fifo_clear_irq();
|
multicore_fifo_clear_irq();
|
||||||
gpio_put(25, true);
|
//gpio_put(25, true);
|
||||||
continue_:
|
continue_:
|
||||||
irq_set_enabled(irq, true);
|
irq_set_enabled(irq, true);
|
||||||
}
|
}
|
||||||
|
@ -151,6 +151,7 @@ static void CORE1_FUNC(glitch_core1_thread_core1_gpio)(void) {
|
||||||
CORE1_PRE_CALC();
|
CORE1_PRE_CALC();
|
||||||
|
|
||||||
__WFI();
|
__WFI();
|
||||||
|
//while (!(sio_hw->gpio_in & (1u<<gpio))) ;
|
||||||
iobank0_hw->intr[gpio>>3] = event << 4*(gpio&7); // acknowledge irq
|
iobank0_hw->intr[gpio>>3] = event << 4*(gpio&7); // acknowledge irq
|
||||||
bool arm = *(volatile bool*)¶m_cur.armed;
|
bool arm = *(volatile bool*)¶m_cur.armed;
|
||||||
if (!arm) continue;
|
if (!arm) continue;
|
||||||
|
@ -166,6 +167,7 @@ static void CORE1_FUNC(glitch_core1_thread_core1_gpio)(void) {
|
||||||
sio_hw->gpio_clr = iom;
|
sio_hw->gpio_clr = iom;
|
||||||
cont:
|
cont:
|
||||||
irq_set_enabled(irq, true);
|
irq_set_enabled(irq, true);
|
||||||
|
//while ((sio_hw->gpio_in & (1u<<gpio))) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
__attribute__((__noreturn__))
|
__attribute__((__noreturn__))
|
||||||
|
@ -178,6 +180,7 @@ static void CORE1_FUNC(glitch_core1_thread_pio)(void) {
|
||||||
irq_set_enabled(irq, true);
|
irq_set_enabled(irq, true);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
//gpio_put(25, gpio_get(10));
|
||||||
CORE1_PRE_CALC();
|
CORE1_PRE_CALC();
|
||||||
(void)iom;
|
(void)iom;
|
||||||
param_cur.offset_ns.cur = off;
|
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_push_off_len(trigctl_pio, trigctl_sm, off>>2, len>>2);
|
||||||
|
|
||||||
trigctl_wait_glitch_irq(trigctl_pio, trigctl_sm, true);
|
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;
|
//sio_hw->gpio_togl = 1u<<25;
|
||||||
|
trigctl_ack_glitch_irq(trigctl_pio, trigctl_sm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -252,7 +252,7 @@ inline static enum tool78_stat tool78_data_recv(struct tool78_hw* hw,
|
||||||
/*#define tool78_wait_status(hw, l, timeout_us, ...) \
|
/*#define tool78_wait_status(hw, l, timeout_us, ...) \
|
||||||
tool78_wait_status__impl(hw, l, timeout_us, __VA_OPT__(1 ? __VA_ARGS__ : ) -1) \
|
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) {
|
/*if (hw->target == tool78k0_spi && timeout_us >= 0) {
|
||||||
busy_wait_us_32(timeout_us);
|
busy_wait_us_32(timeout_us);
|
||||||
timeout_us *= 2;
|
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);
|
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;
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*ver = bytes[0] | ((uint16_t)bytes[1] << 8);
|
// BCD, so big-endian
|
||||||
|
*ver = bytes[1] | ((uint16_t)bytes[0] << 8);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,10 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// NOTE:
|
||||||
|
// * RL78/x1y flash block size: 0x400
|
||||||
|
// * RL78/x2y flash block size: 0x800
|
||||||
|
|
||||||
enum tool78_target {
|
enum tool78_target {
|
||||||
tool78k0_uart2 = 0x12,
|
tool78k0_uart2 = 0x12,
|
||||||
tool78k0_spi = 0x13,
|
tool78k0_spi = 0x13,
|
||||||
|
@ -44,7 +48,8 @@ enum tool78_entry {
|
||||||
// TOOL0 initial byte values
|
// TOOL0 initial byte values
|
||||||
tool78_entry_rl78_uart1 = 0x3a,
|
tool78_entry_rl78_uart1 = 0x3a,
|
||||||
tool78_entry_rl78_uart2 = 0x00,
|
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
|
// 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)
|
// execute code at 0xf07e0 (TODO: verify addr across versions)
|
||||||
tool78ocd_cmd_exec = 0x94,
|
tool78ocd_cmd_exec = 0x94,
|
||||||
tool78ocd_cmd_exit_reti = 0x95, // TODO: what is this?
|
tool78ocd_cmd_exit_reti = 0x95, // TODO: what is this?
|
||||||
|
// TODO: 96 too?
|
||||||
tool78ocd_cmd_exit_ram = 0x97, // TODO: what is this?
|
tool78ocd_cmd_exit_ram = 0x97, // TODO: what is this?
|
||||||
|
|
||||||
tool78ocd_cmdg10_connect = 0x55,
|
tool78ocd_cmdg10_connect = 0x55,
|
||||||
|
|
135
test/rl78/test.S
135
test/rl78/test.S
|
@ -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:
|
|
||||||
*/
|
|
|
@ -0,0 +1 @@
|
||||||
|
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
|
||||||
|
|
|
@ -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*/
|
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
*/
|
Loading…
Reference in New Issue