From a2f5c26a8ac422e9318733fc4d30cef9eb96b3cb Mon Sep 17 00:00:00 2001
From: Daniel Friesel <daniel.friesel@uos.de>
Date: Mon, 27 May 2019 10:19:43 +0200
Subject: Add transaction object with retry/abort functions

---
 src/app/transactiontest/main.cc | 48 ++++++++++++++---------------------
 src/app/transactiontest/util.S  | 56 ++++++++++++++++++++++++++++++++++++-----
 2 files changed, 69 insertions(+), 35 deletions(-)

(limited to 'src/app')

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
-- 
cgit v1.2.3