arch: riscv32: fix IRQ handling bugs when benchmarking
arch: riscv32: fix IRQ handling bugs when benchmarking

The way that CONFIG_EXECUTION_BENCHMARKING=y is handled on this
architecture is incorrect. The goals are:

- call read_timer_start_of_isr() as close as possible to the
  beginning of the ISR
- call read_timer_end_of_isr() after all preparations have
  been made to call the driver-level IRQ handler, but it hasn't
  been called yet

The current implementation could cause kernel crashes, though.

The read_timer_start_of_isr() call is made before saving MEPC or any
SoC-specific context. The MEPC issue is not that big of a deal, but
doing it before saving SoC context could clobber state that hasn't
been saved yet and corrupt the kernel.

One example is a pulpino style RISC-V SoC. Some Pulpino cores have
extra registers that are used for ISA extensions used to generate code
for C loops. There's no guarantee read_timer_start_of_isr() will never
have a loop inside: in fact, the RISC-V User-Level ISA v2.2 explicitly
recommends using a loop to get the 64-bit value of the "cycle" CSR. A
Pulpino-like SoC with a cycle CSR could thus naturally have a
read_timer_start_of_isr() implementation that involves loops. Saving
the loop state before reading the timer would then be needed.

Fix this issue by moving the call to read_timer_start_of_isr to after
all context saving is done. (This is a fairer comparison to Arm
Cortex-M SoCs anyway, since register stacking is performed in hardware
on Cortex M and is done before the first ISR instruction executes.)

The call to read_timer_end_of_isr() has an issue as well: it's called
after the ISR's argument has been stored in a0 and the ISR address is
in t1, but before actually calling the ISR itself.

In the standard RV32I calling convention, both t1 and a0 are caller
saved, so read_timer_end_of_isr() is within its rights to set them to
any garbage, which we'll happily treat as a function and its argument
and execute.

Avoid that possibility by saving the register values to the stack in
this configuration.

Signed-off-by: Marti Bolivar <fd5da480b758a78208111e6ae5c6806e1f887137@foundries.io>

finikorg/zephyr,nashif/zephyr,finikorg/zephyr,Vudentz/zephyr,explora26/zephyr,Vudentz/zephyr,explora26/zephyr,ldts/zephyr,zephyrproject-rtos/zephyr,GiulianoFranchetto/zephyr,galak/zephyr,nashif/zephyr,Vudentz/zephyr,punitvara/zephyr,GiulianoFranchetto/zephyr,punitvara/zephyr,ldts/zephyr,zephyrproject-rtos/zephyr,zephyrproject-rtos/zephyr,galak/zephyr,punitvara/zephyr,ldts/zephyr,Vudentz/zephyr,punitvara/zephyr,galak/zephyr,explora26/zephyr,finikorg/zephyr,finikorg/zephyr,zephyrproject-rtos/zephyr,nashif/zephyr,ldts/zephyr,finikorg/zephyr,galak/zephyr,galak/zephyr,ldts/zephyr,Vudentz/zephyr,zephyrproject-rtos/zephyr,GiulianoFranchetto/zephyr,nashif/zephyr,GiulianoFranchetto/zephyr,Vudentz/zephyr,GiulianoFranchetto/zephyr,explora26/zephyr,explora26/zephyr,nashif/zephyr,punitvara/zephyr