Machine Timer Interruption handling - Difference of behavior between Spike and C++ Emulator

464 views
Skip to first unread message

Noureddine AIT SAID

unread,
May 14, 2018, 9:02:06 AM5/14/18
to RISC-V SW Dev
​Hello,

I'm trying to understand interrupts in RISC-V. Especially Machine Timer Interrupts.
Inspiring from riscv-pk i could do that using SBI calls in supervisor mode and handle them correctly.

However in M-mode, bare-metal, things were a little bit confusing. Inspired from riscv-tests/debug/programs/interrupt.c, i tried to catch a simple Machine Timer interrupt, I display a message then i set timecmp to (uint64_t)-1ULL to set the timer compare register to disable the timer as mentioned in a presentation of Mr. Krste Asanovic [here]. The thing is it fails there when I want to reconfigure the mtimecmp with a new value in the interrupt_handler, here are my test conclusions:

  • In spike, I catch machine timer interrupt, but when I write to mtimecmp I get MCause = 1 : fetch access exception and it stops.

  • In C++ Emulator (generated by verilator), I catch machine timer interrupt too, but when I write to mtimecmp I get MCause = 2 : illegal instruction exception

I really would like to understand:

- Is there are fundamental differences between these two environments (Spike and C++ Emulator) when it comes to interrupts?

- Why does it fail when I set the mtimecmp inside the interrupt handler (it doesn't fail when I've configured it the first time before the interrupt)? Did I forgot something maybe?

Concerning HW, I use Rocket-Chip with DefaultConfig.

Posted that here as an issue https://github.com/riscv/riscv-isa-sim/issues/202

Best reagards!

noureddine-as.


Megan Wachs

unread,
May 14, 2018, 9:09:29 AM5/14/18
to Noureddine AIT SAID, RISC-V SW Dev
— what is mtval in each case? That can give you more info  on what is wrong with the address or instruction

— is your trap vector aligned in each case? 

—how are you compiling and linking your programs? Are you trying to run on incompatible design? Are you sure the address for mtime is the same for both platforms?

—have you looked at the trace (output with +verbose) too see exactly how your program is executing? 

--
You received this message because you are subscribed to the Google Groups "RISC-V SW Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sw-dev+un...@groups.riscv.org.
To post to this group, send email to sw-...@groups.riscv.org.
Visit this group at https://groups.google.com/a/groups.riscv.org/group/sw-dev/.
To view this discussion on the web visit https://groups.google.com/a/groups.riscv.org/d/msgid/sw-dev/CALR3b2B3ziGVowvHTFfBSGG-1vKROzsK95EbKM%3DU8hoi7hdV0g%40mail.gmail.com.
--
Megan A. Wachs
Engineer | SiFive, Inc 
1875 South Grant Street
Suite 600
San Mateo, CA 94402

Noureddine AIT SAID

unread,
May 14, 2018, 12:19:55 PM5/14/18
to Megan Wachs, Noureddine AIT SAID, RISC-V SW Dev
Thanks for you reply Megan.

--- Concerning mtval
// I use this
#define MTVAL        (*(volatile long long *)(CSR_MTVAL))

   - In spike: I get the following:
ERROR: invalid load from debug module: 1 bytes at 0x0000000000000343
     The message is printed many times then Spike stops.

   - In the C++ Emulator: I get:
# The first time I catch the Timer Interrupt
mcause = 8000000000000007   -   mtval = 1000730084041300
[handle_trap] - Interrupt : machine timer interrupt .. Executing interrupt_handler

# Writing to timercmp inside the interrupt handler causes the following exception
mcause = 2   -   mtval = 1000730084041300
[handle_trap] - Exception : illegal instruction .. Executing trap_handler


--- Is the trap vector alligned?
I'm not sure about this, I didn't put a vector_table like is done in riscv-pk (machine part here).

— how are you compiling and linking your programs?
I'm using on RV64IMAFD isa + this linker.
For emulation i'm using DefaultConfig. So I think designs are compatible.

Are you sure the address for mtime is the same for both platforms?
Yes they use the same addresses:
#define MTIMECMP_BASE 0x4000
#define MTIME_BASE 0xbff8

— Have you looked at the trace (output with +verbose) too see exactly how your program is executing? 
​Yeah I tried. My conclusion is that the source of the problem is the line is what provokes the exception. Otherwise if i delete it, the interrupt doesn't get cleared and so the handler keeps executing indefinitly:
​      MTIMECMP[0] = MTIME + 0x300; // The source of the problem
​This is my source code here. As you can see when I set the timecmp for the first time
MTIMECMP[0] = MTIME + 0x500;
It configures the timer interrupt well, but when I do it again inside the interrupt handler it causes that exception.

Thanks a lot for your help and your time.
​Best regards,
​Noureddine.​



On Mon, May 14, 2018 at 3:09 PM, Megan Wachs <me...@sifive.com> wrote:
— what is mtval in each case? That can give you more info  on what is wrong with the address or instruction

— is your trap vector aligned in each case? 

—how are you compiling and linking your programs? Are you trying to run on incompatible design? Are you sure the address for mtime is the same for both platforms?

—have you looked at the trace (output with +verbose) too see exactly how your program is executing? 

On Mon, May 14, 2018 at 06:02 n AIT SAID <noureddin...@gmail.com> wrote:
​Hello,

I'm trying to understand interrupts in RISC-V. Especially Machine Timer Interrupts.
Inspiring from riscv-pk i could do that using SBI calls in supervisor mode and handle them correctly.

However in M-mode, bare-metal, things were a little bit confusing. Inspired from riscv-tests/debug/programs/interrupt.c, i tried to catch a simple Machine Timer interrupt, I display a message then i set timecmp to (uint64_t)-1ULL to set the timer compare register to disable the timer as mentioned in a presentation of Mr. Krste Asanovic [here]. The thing is it fails there when I want to reconfigure the mtimecmp with a new value in the interrupt_handler, here are my test conclusions:

  • In spike, I catch machine timer interrupt, but when I write to mtimecmp I get MCause = 1 : fetch access exception and it stops.

  • In C++ Emulator (generated by verilator), I catch machine timer interrupt too, but when I write to mtimecmp I get MCause = 2 : illegal instruction exception

I really would like to understand:

- Is there are fundamental differences between these two environments (Spike and C++ Emulator) when it comes to interrupts?

- Why does it fail when I set the mtimecmp inside the interrupt handler (it doesn't fail when I've configured it the first time before the interrupt)? Did I forgot something maybe?

Concerning HW, I use Rocket-Chip with DefaultConfig.

Posted that here as an issue https://github.com/riscv/riscv-isa-sim/issues/202

Best reagards!

noureddine-as.


--
You received this message because you are subscribed to the Google Groups "RISC-V SW Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sw-dev+unsubscribe@groups.riscv.org.
--
You received this message because you are subscribed to the Google Groups "RISC-V SW Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sw-dev+unsubscribe@groups.riscv.org.

To post to this group, send email to sw-...@groups.riscv.org.
Visit this group at https://groups.google.com/a/groups.riscv.org/group/sw-dev/.

Noureddine AIT SAID

unread,
May 15, 2018, 8:16:45 AM5/15/18
to Megan Wachs, Noureddine AIT SAID, RISC-V SW Dev
Hello,

I confirm your point Megan. The cause is a misaligned fetch.
Fixed that by directly writing my trap handler in the entry.S in assembly.
Although still confused about the differences between Emulator and Spike's behavior.

Thank you for your help.

Best regards.
​Noureddine.​


On Mon, May 14, 2018 at 3:09 PM, Megan Wachs <me...@sifive.com> wrote:
Reply all
Reply to author
Forward
0 new messages