stuff that doesn't work

This commit is contained in:
Triss 2022-04-10 02:43:28 +02:00
parent 0e63d67649
commit 59fa779864
3 changed files with 65 additions and 7 deletions

View File

@ -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
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.
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
@ -113,6 +122,7 @@ described near the end, the article is quite large.
[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
execution? (Most likely, just like interrupts can, I simply haven't checked.)
1. Dumping of the `0x1b00`..`0x1bff` region still needs to happen.
## Hashes
@ -126,6 +136,15 @@ with BSL 00.08.35.B3:
| SHA-256 | `e4d0d171013f847a357eebe5467bcd413ecb41dc01424b7e4ee636538d820766` |
| 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
The code in `src/main.c` will dump the content of the BSL to `eUSCI_A0` in UART

View File

@ -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]
delta = -1
if len(recs) > 1:
if len(recs) > 0:
rec_ = Rec(ticks, delta, pc, sp, sr, gp, stack)
for i in range(2, min(15, len(recs))):
if recs[-i] == recs[-1]:

View File

@ -40,6 +40,10 @@ static uint8_t stackbak[16]={0};
__attribute__((__persistent__))
static uint16_t curticks = 1;
extern uint16_t done_irq;
__attribute__((__persistent__, __used__))
uint16_t done_irq = 0;
extern uint16_t curaddr;
__attribute__((__persistent__))
@ -56,7 +60,7 @@ typedef void (*bsl_fn)(void);
#define END_CYC 0xffffu
// DUMP_MODE == 0 => insn trace mode
#define DUMP_MODE 1
#define DUMP_MODE 0
#define DUMP_CYC_OFF 14
void do_trace(void);
@ -67,10 +71,11 @@ __attribute__((__no_inline__)) void do_trace(void) {
// init timer TA0
__bic_SR_register(GIE);
#ifdef DUMP_MODE
#if DUMP_MODE
traceaddr = 0x1002;
TA1CCR0 = DUMP_CYC_OFF;
#else
done_irq = 0;
TA1CCR0 = curticks;
#endif
TA1CCTL0 = CCIE;
@ -90,7 +95,7 @@ __attribute__((__no_inline__)) void do_trace(void) {
"mov.w #0xbeef, r14\n"
"mov.w #0xaaaa, r15\n"
#ifdef DUMP_MODE
#if DUMP_MODE
// extra 0x1002 magic
"mov.w curaddr, sp\n"
#endif
@ -106,9 +111,15 @@ __attribute__((__no_inline__)) void do_trace(void) {
void do_collect(uint16_t* sp);
__attribute__((__used__, __no_inline__))
void do_collect(uint16_t* sp) {
void do_collect(uint16_t* sp) {
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
uint16_t v1 = sp[2*(12-4)];
uint16_t v2 = sp[2*(13-4)];
@ -128,14 +139,16 @@ __attribute__((__used__, __no_inline__))
if (curticks < START_SOFT) goto next_iter;
#endif
uint16_t sr = sp[24];
uint32_t pc = sp[25];
//uint16_t pc16 = pc;
// general purpose registers
for (int i = 0; i < 12; ++i) {
uint32_t v = sp[(i*2)+0] | ((uint32_t)sp[(i*2)+1] << 16);
regbak[i+4] = v;
}
uint16_t sr = sp[24];
uint32_t pc = sp[25];
pc |= ((uint32_t)(sr & 0xf000) << (16-12));
sr &= 0xfff;
@ -178,11 +191,36 @@ __attribute__((__interrupt__(TIMER1_A0_VECTOR), __naked__))
void Timer_A1_ISR(void) {
asm volatile(
".extern do_collect\n"
".extern done_irq\n"
".extern curticks\n"
//"bis #0x3, P1OUT\n"
#if DUMP_MODE
// get a stack we can do stuff with
// (sp is currently in bsl space)
"mov.a #(__stack-8), sp\n"
#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"
"mov.a sp, r12\n"
"call #do_collect\n"
@ -215,6 +253,7 @@ int main(void) {
puts("hello world!\r\n");
done_irq = 0;
do_trace();
__builtin_unreachable();
}