diff options
| author | Daniel Friesel <daniel.friesel@uos.de> | 2019-05-27 10:19:43 +0200 | 
|---|---|---|
| committer | Daniel Friesel <daniel.friesel@uos.de> | 2019-05-27 10:19:43 +0200 | 
| commit | a2f5c26a8ac422e9318733fc4d30cef9eb96b3cb (patch) | |
| tree | 5f36264b0e229c55a72843531f32fdf35687b149 /src/app | |
| parent | 6e43e8e9a59569b573628c84d68af26f284c8c4e (diff) | |
Add transaction object with retry/abort functions
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 | 
