summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Friesel <daniel.friesel@uos.de>2019-05-27 10:19:43 +0200
committerDaniel Friesel <daniel.friesel@uos.de>2019-05-27 10:19:43 +0200
commita2f5c26a8ac422e9318733fc4d30cef9eb96b3cb (patch)
tree5f36264b0e229c55a72843531f32fdf35687b149 /src
parent6e43e8e9a59569b573628c84d68af26f284c8c4e (diff)
Add transaction object with retry/abort functions
Diffstat (limited to 'src')
-rw-r--r--src/app/transactiontest/main.cc48
-rw-r--r--src/app/transactiontest/util.S56
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