stuff that doesn't work
This commit is contained in:
parent
0e63d67649
commit
59fa779864
19
README.md
19
README.md
|
@ -104,6 +104,15 @@ described near the end, the article is quite large.
|
||||||
1. ~~The BSL sets up Timer A, while the datasheet only mentions Timer B usage
|
1. ~~The BSL sets up Timer A, while the datasheet only mentions Timer B usage
|
||||||
in *other* BSLs, and nothing about this one.~~ This is wrong, it changes the
|
in *other* BSLs, and nothing about this one.~~ This is wrong, it changes the
|
||||||
clock settings, which has an influence on which clock source a timer uses.
|
clock settings, which has an influence on which clock source a timer uses.
|
||||||
|
1. The BSL communication method does not depend on the part number (eg. 5994 vs
|
||||||
|
59941), only the values in TLV are checked.
|
||||||
|
1. While the code has paths for other UART baudrate settings for the
|
||||||
|
communication interface, only one is available.
|
||||||
|
1. The memory area from `0x1b00` to `0x1bff` also contains ROM code, with its
|
||||||
|
own Z-area (also at the beginning, also 8 bytes in size). It has three
|
||||||
|
entrypoints, the fourth is an infinite loop. (`0x3c00..0x3fff` looks like
|
||||||
|
the same type of execute-only memory at first, but actually contains nothing,
|
||||||
|
at least not according to the techniques used here.)
|
||||||
|
|
||||||
## What has not been checked
|
## What has not been checked
|
||||||
|
|
||||||
|
@ -113,6 +122,7 @@ described near the end, the article is quite large.
|
||||||
[MerryMage's GBA BIOS dump](https://mary.rs/lab/gbabios/))
|
[MerryMage's GBA BIOS dump](https://mary.rs/lab/gbabios/))
|
||||||
1. DMA: can a DMA transfer be used to change the stack contents during BSL
|
1. DMA: can a DMA transfer be used to change the stack contents during BSL
|
||||||
execution? (Most likely, just like interrupts can, I simply haven't checked.)
|
execution? (Most likely, just like interrupts can, I simply haven't checked.)
|
||||||
|
1. Dumping of the `0x1b00`..`0x1bff` region still needs to happen.
|
||||||
|
|
||||||
## Hashes
|
## Hashes
|
||||||
|
|
||||||
|
@ -126,6 +136,15 @@ with BSL 00.08.35.B3:
|
||||||
| SHA-256 | `e4d0d171013f847a357eebe5467bcd413ecb41dc01424b7e4ee636538d820766` |
|
| SHA-256 | `e4d0d171013f847a357eebe5467bcd413ecb41dc01424b7e4ee636538d820766` |
|
||||||
| SHA-512 | `fed28a7e9643a551789075b79d9b04fa6e8cdca74d783c1c3830ece07e5c9141dda9532b3c442416a1ddab90d752e679c6918c0d5333ac6da9fd23ab6c33d1bb` |
|
| SHA-512 | `fed28a7e9643a551789075b79d9b04fa6e8cdca74d783c1c3830ece07e5c9141dda9532b3c442416a1ddab90d752e679c6918c0d5333ac6da9fd23ab6c33d1bb` |
|
||||||
|
|
||||||
|
## Region 2 WIP stuff
|
||||||
|
|
||||||
|
* `0x1b00` entrypoint: basically halts the CPU. Not very useful.
|
||||||
|
* `0x1b02` jumps to `0x1bc2` which almost immediately disables interrupts.
|
||||||
|
* `0x1b04` jumps to `0x1bd6` which almost immediately disables interrupts.
|
||||||
|
|
||||||
|
Haven't been able to get around the IRQ disable thing yet... TODO: try NMI? Or
|
||||||
|
some timer IRQ sneakiness to get around the IRQ disable code.
|
||||||
|
|
||||||
## Proof of concept
|
## Proof of concept
|
||||||
|
|
||||||
The code in `src/main.c` will dump the content of the BSL to `eUSCI_A0` in UART
|
The code in `src/main.c` will dump the content of the BSL to `eUSCI_A0` in UART
|
||||||
|
|
|
@ -72,7 +72,7 @@ with serial.Serial(sys.argv[1] if len(sys.argv) > 1 else "/dev/ttyACM1", 9600, t
|
||||||
stack = [int(x,16) for x in stack]
|
stack = [int(x,16) for x in stack]
|
||||||
|
|
||||||
delta = -1
|
delta = -1
|
||||||
if len(recs) > 1:
|
if len(recs) > 0:
|
||||||
rec_ = Rec(ticks, delta, pc, sp, sr, gp, stack)
|
rec_ = Rec(ticks, delta, pc, sp, sr, gp, stack)
|
||||||
for i in range(2, min(15, len(recs))):
|
for i in range(2, min(15, len(recs))):
|
||||||
if recs[-i] == recs[-1]:
|
if recs[-i] == recs[-1]:
|
||||||
|
|
51
src/main.c
51
src/main.c
|
@ -40,6 +40,10 @@ static uint8_t stackbak[16]={0};
|
||||||
__attribute__((__persistent__))
|
__attribute__((__persistent__))
|
||||||
static uint16_t curticks = 1;
|
static uint16_t curticks = 1;
|
||||||
|
|
||||||
|
extern uint16_t done_irq;
|
||||||
|
__attribute__((__persistent__, __used__))
|
||||||
|
uint16_t done_irq = 0;
|
||||||
|
|
||||||
|
|
||||||
extern uint16_t curaddr;
|
extern uint16_t curaddr;
|
||||||
__attribute__((__persistent__))
|
__attribute__((__persistent__))
|
||||||
|
@ -56,7 +60,7 @@ typedef void (*bsl_fn)(void);
|
||||||
#define END_CYC 0xffffu
|
#define END_CYC 0xffffu
|
||||||
|
|
||||||
// DUMP_MODE == 0 => insn trace mode
|
// DUMP_MODE == 0 => insn trace mode
|
||||||
#define DUMP_MODE 1
|
#define DUMP_MODE 0
|
||||||
#define DUMP_CYC_OFF 14
|
#define DUMP_CYC_OFF 14
|
||||||
|
|
||||||
void do_trace(void);
|
void do_trace(void);
|
||||||
|
@ -67,10 +71,11 @@ __attribute__((__no_inline__)) void do_trace(void) {
|
||||||
|
|
||||||
// init timer TA0
|
// init timer TA0
|
||||||
__bic_SR_register(GIE);
|
__bic_SR_register(GIE);
|
||||||
#ifdef DUMP_MODE
|
#if DUMP_MODE
|
||||||
traceaddr = 0x1002;
|
traceaddr = 0x1002;
|
||||||
TA1CCR0 = DUMP_CYC_OFF;
|
TA1CCR0 = DUMP_CYC_OFF;
|
||||||
#else
|
#else
|
||||||
|
done_irq = 0;
|
||||||
TA1CCR0 = curticks;
|
TA1CCR0 = curticks;
|
||||||
#endif
|
#endif
|
||||||
TA1CCTL0 = CCIE;
|
TA1CCTL0 = CCIE;
|
||||||
|
@ -90,7 +95,7 @@ __attribute__((__no_inline__)) void do_trace(void) {
|
||||||
"mov.w #0xbeef, r14\n"
|
"mov.w #0xbeef, r14\n"
|
||||||
"mov.w #0xaaaa, r15\n"
|
"mov.w #0xaaaa, r15\n"
|
||||||
|
|
||||||
#ifdef DUMP_MODE
|
#if DUMP_MODE
|
||||||
// extra 0x1002 magic
|
// extra 0x1002 magic
|
||||||
"mov.w curaddr, sp\n"
|
"mov.w curaddr, sp\n"
|
||||||
#endif
|
#endif
|
||||||
|
@ -106,9 +111,15 @@ __attribute__((__no_inline__)) void do_trace(void) {
|
||||||
|
|
||||||
void do_collect(uint16_t* sp);
|
void do_collect(uint16_t* sp);
|
||||||
__attribute__((__used__, __no_inline__))
|
__attribute__((__used__, __no_inline__))
|
||||||
void do_collect(uint16_t* sp) {
|
void do_collect(uint16_t* sp) {
|
||||||
TA1CTL &= ~(uint16_t)(TAIE|MC__UP);
|
TA1CTL &= ~(uint16_t)(TAIE|MC__UP);
|
||||||
|
|
||||||
|
// 0x1bc2/4 and 0x1bd6/8 contain a bic #GIE, sr instruction! these should be 2 bytes in size
|
||||||
|
/*if (pc16 == 0x1bc2 || pc16 == 0x1bc4 || pc16 == 0x1bd6 || pc16 == 0x1bd8) {
|
||||||
|
sp[24] |=
|
||||||
|
}*/
|
||||||
|
// 0x1b96 does a jump to ???? (probably from a memory location?)
|
||||||
|
|
||||||
#if DUMP_MODE
|
#if DUMP_MODE
|
||||||
uint16_t v1 = sp[2*(12-4)];
|
uint16_t v1 = sp[2*(12-4)];
|
||||||
uint16_t v2 = sp[2*(13-4)];
|
uint16_t v2 = sp[2*(13-4)];
|
||||||
|
@ -128,14 +139,16 @@ __attribute__((__used__, __no_inline__))
|
||||||
if (curticks < START_SOFT) goto next_iter;
|
if (curticks < START_SOFT) goto next_iter;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
uint16_t sr = sp[24];
|
||||||
|
uint32_t pc = sp[25];
|
||||||
|
//uint16_t pc16 = pc;
|
||||||
|
|
||||||
// general purpose registers
|
// general purpose registers
|
||||||
for (int i = 0; i < 12; ++i) {
|
for (int i = 0; i < 12; ++i) {
|
||||||
uint32_t v = sp[(i*2)+0] | ((uint32_t)sp[(i*2)+1] << 16);
|
uint32_t v = sp[(i*2)+0] | ((uint32_t)sp[(i*2)+1] << 16);
|
||||||
regbak[i+4] = v;
|
regbak[i+4] = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t sr = sp[24];
|
|
||||||
uint32_t pc = sp[25];
|
|
||||||
pc |= ((uint32_t)(sr & 0xf000) << (16-12));
|
pc |= ((uint32_t)(sr & 0xf000) << (16-12));
|
||||||
sr &= 0xfff;
|
sr &= 0xfff;
|
||||||
|
|
||||||
|
@ -178,11 +191,36 @@ __attribute__((__interrupt__(TIMER1_A0_VECTOR), __naked__))
|
||||||
void Timer_A1_ISR(void) {
|
void Timer_A1_ISR(void) {
|
||||||
asm volatile(
|
asm volatile(
|
||||||
".extern do_collect\n"
|
".extern do_collect\n"
|
||||||
|
".extern done_irq\n"
|
||||||
|
".extern curticks\n"
|
||||||
|
|
||||||
//"bis #0x3, P1OUT\n"
|
//"bis #0x3, P1OUT\n"
|
||||||
#if DUMP_MODE
|
#if DUMP_MODE
|
||||||
|
// get a stack we can do stuff with
|
||||||
|
// (sp is currently in bsl space)
|
||||||
"mov.a #(__stack-8), sp\n"
|
"mov.a #(__stack-8), sp\n"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*#if !DUMP_MODE
|
||||||
|
// do some hackery
|
||||||
|
"bit.w #0, done_irq\n"
|
||||||
|
"jnz .Lregular\n"
|
||||||
|
|
||||||
|
// skip pc forward by 4
|
||||||
|
"add.w #4, 2(sp)\n"
|
||||||
|
// set GIE in sr
|
||||||
|
"bis.w #8, 0(sp)\n"
|
||||||
|
// set timer counter for next IRQ for trace
|
||||||
|
"mov.w #1, TA1CCR0\n"
|
||||||
|
// restart timer
|
||||||
|
"bis.w #4, TA1CTL\n"
|
||||||
|
// done it now
|
||||||
|
"mov.w #1, done_irq\n"
|
||||||
|
// continue as usual
|
||||||
|
"reti\n"
|
||||||
|
#endif*/
|
||||||
|
|
||||||
|
".Lregular:\n"
|
||||||
"pushm.a #12, r15\n"
|
"pushm.a #12, r15\n"
|
||||||
"mov.a sp, r12\n"
|
"mov.a sp, r12\n"
|
||||||
"call #do_collect\n"
|
"call #do_collect\n"
|
||||||
|
@ -215,6 +253,7 @@ int main(void) {
|
||||||
|
|
||||||
puts("hello world!\r\n");
|
puts("hello world!\r\n");
|
||||||
|
|
||||||
|
done_irq = 0;
|
||||||
do_trace();
|
do_trace();
|
||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue