OpenCores

* Amber ARM-compatible core

Issue List
Broken LDMIA for user mode register load #17
Closed sleary opened this issue about 9 years ago
sleary commented about 9 years ago

The following code should load R13_user with 01818af0 but instead loads it into r13_svc

_start ;; ensure supervisor mode TEQP PC,#3 ADR R13,datatable ;; load into the usermode register bank!!! LDMIA R13!,{R0-R14}^

done B done NOP NOP

datatable & &03886448
& &00070010
& &00000010
& &0000027f
& &01818b04
& &00001480
& &ffffffff
& &000003be
& &0000028c
& &000400c0
& &0386cd1c
& &00000000
& &01801a84
& &01818af0
& &23885c00

sleary commented about 9 years ago

Part of the manual that deals with this behaviour says...

LDM - "In non-user mode where R15 is not in the transfer list, S=1 is used to force loaded values into user registers instead of the current bank."

STM - "In used mode the S bit is ignored but in other modes it has a second interpretation. S = 1 is used to force transfers to take values from the current user register bank. This is useful for saving the user state on processor switches".

sleary commented about 9 years ago

Mistyped -- STM - "In used mode the S bit is ignored but in other modes it has a second interpretation. S = 1 is used to force transfers to take values from the user register bank instead of from the current register bank. This is useful for saving the user state on processor switches".

sleary commented about 9 years ago

This instruction works fine if the writeback bit isnt set.

e.g.

LDMIA R13,{R0-R14}^

so it seems there is missing logic for the writeback case.

sleary commented about 9 years ago

Ok found this one too...

Looks like the multiple transfer code rightly doesnt user_mode_regs_load_nxt if writeback is on for the first 2 cycles... eg

// LDM: load into user mode registers, when in priviledged mode
// DOnt use mtrans_r15 here because its not loaded yet
if ( {instruction22:20,instruction15} == 4'b1010 ) user_mode_regs_load_nxt = 1'd1;

however this needs to ignore bit 21 on later cycles. e.g.

if ( {instruction22, instruction20,mtrans_r15} == 4'b110 ) user_mode_regs_load_nxt = 1'd1;

Looks like a copy and paste error.

csantifort closed this about 9 years ago

Assignee
No one
Labels
Bug