Loading src/app/transactiontest/main.cc +19 −29 Original line number Diff line number Diff line Loading @@ -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); { Transaction tx; kout << dec << i << endl; i++; if (i == 5) { save_state(); if (!gpio.read(GPIO::p4_5)) { tx.abort(); } if (i == 10) { restore_state(); } } Loading @@ -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(); Loading src/app/transactiontest/util.S +50 −6 Original line number Diff line number Diff line .global asm_save_toc .global asm_load_toc .global asm_save_all .global asm_load_all .global asm_load_mem stack_backup: .space 2048 Loading @@ -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 Loading @@ -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 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 Loading
src/app/transactiontest/main.cc +19 −29 Original line number Diff line number Diff line Loading @@ -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); { Transaction tx; kout << dec << i << endl; i++; if (i == 5) { save_state(); if (!gpio.read(GPIO::p4_5)) { tx.abort(); } if (i == 10) { restore_state(); } } Loading @@ -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(); Loading
src/app/transactiontest/util.S +50 −6 Original line number Diff line number Diff line .global asm_save_toc .global asm_load_toc .global asm_save_all .global asm_load_all .global asm_load_mem stack_backup: .space 2048 Loading @@ -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 Loading @@ -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 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