diff options
Diffstat (limited to 'src/app')
-rw-r--r-- | src/app/transactiontest/main.cc | 48 | ||||
-rw-r--r-- | src/app/transactiontest/util.S | 56 |
2 files changed, 69 insertions, 35 deletions
diff --git a/src/app/transactiontest/main.cc b/src/app/transactiontest/main.cc index e359e67..cb2d86e 100644 --- a/src/app/transactiontest/main.cc +++ b/src/app/transactiontest/main.cc @@ -8,37 +8,31 @@ #endif extern "C" { - void asm_save_toc(); - void asm_load_toc(); + void asm_save_all(); + void asm_load_all(); + void asm_load_mem(); } -volatile bool __attribute__((section(".text"))) have_state = false; uint16_t i = 0; -void restore_state() -{ - if (!have_state) { - return; - } - asm_load_toc(); -} - -void save_state() -{ - asm_save_toc(); - have_state = true; -} +class Transaction { + public: + inline Transaction() { asm_save_all(); } + inline ~Transaction() {} + inline void retry() { asm_load_all(); } + inline void abort() { asm_load_mem(); } +}; void loop(void) { gpio.led_toggle(1); - kout << dec << i << endl; - i++; - if (i == 5) { - save_state(); - } - if (i == 10) { - restore_state(); + { + Transaction tx; + kout << dec << i << endl; + i++; + if (!gpio.read(GPIO::p4_5)) { + tx.abort(); + } } } @@ -48,15 +42,11 @@ int main(void) gpio.setup(); kout.setup(); - restore_state(); + //restore_state(); gpio.led_on(0); + gpio.input(GPIO::p4_5, 1); kout << "Hello, World!" << endl; - kout << "Test, World!" << endl; - kout << dec << uptime.get_cycles() << endl; - kout << dec << uptime.get_cycles() << endl; - kout << dec << uptime.get_cycles() << endl; - kout << dec << uptime.get_cycles() << endl; arch.idle_loop(); diff --git a/src/app/transactiontest/util.S b/src/app/transactiontest/util.S index bf2530d..c0b1ebc 100644 --- a/src/app/transactiontest/util.S +++ b/src/app/transactiontest/util.S @@ -1,5 +1,6 @@ -.global asm_save_toc -.global asm_load_toc +.global asm_save_all +.global asm_load_all +.global asm_load_mem stack_backup: .space 2048 @@ -7,7 +8,8 @@ stack_backup: sp_backup: .space 2 -asm_save_toc: +asm_save_all: + dint .irp reg,4,5,6,7,8,9,10,11 push r\reg .endr @@ -26,21 +28,63 @@ save_sram_word: pop r11 pop r10 add #12, r1 + eint ret -asm_load_toc: +asm_load_all: + dint + + ; restore SRAM from backup mov #stack_backup, r10 mov #1c00h, r11 - load_sram_word: mov @r10+, 0(r11) add #2, r11 cmp #1c00h+2048, r11 jlo load_sram_word + ; restore stack pointer mov &sp_backup, r1 + + ; restore registers .irp reg,11,10,9,8,7,6,5,4 pop r\reg .endr - ret
\ No newline at end of file + eint + + ; The return address on the stack has been restored from FRAM backup + ; -> execution will continue where asm_save_all was called + ret + +asm_load_mem: + dint + ; save return address in r4 + mov @r1, r4 + + ; restore SRAM from backup + mov #stack_backup, r10 + mov #1c00h, r11 +load_sram_word2: + mov @r10+, 0(r11) + add #2, r11 + cmp #1c00h+2048, r11 + jlo load_sram_word2 + + ; restore stack pointer + mov &sp_backup, r1 + + ; restore old register contents + .irp reg,11,10,9,8,7,6,5 + pop r\reg + .endr + + ; load return address, that is, the address this function was called from. + ; This is not the address which called asm_save_all -- we only want to restore memory contents, not re-execute everything + mov r4, 2(r1) + + ; load remaining register content + pop r4 + + eint + ret |