Skip to content

Latest commit

 

History

History
754 lines (713 loc) · 25.2 KB

test-plan-clic.adoc

File metadata and controls

754 lines (713 loc) · 25.2 KB

RISC-V Fast Interrupt: Architectural Tests Plan

A plan for developing the riscv architectural tests for the Fast Interrupt Extension.

1. Introduction

The point of this test plan is to:

  • Explain what the RISC-V architectural tests try to achieve, both generally and for the fast interrupt architecture in particular.

  • Act as a starting point for verification engineers writing verification plans.

Some useful links:

2. Test bench setup and deterministic sequences

The framework for architectural tests is to load a test (binary) and start a hart, the hart signals finished, results are extraced from memory and verified against a signature. Since interrupts can occur asynchronously it is limiting to create deterministic tests for different implementations with results that can be compared with SAIL model results. For example, with different implementation, a different number of instructions will occur before the pending interrupt bit actually gets set. Depending on the implementation, the execution pc could be a different value than the SAIL model. The following deterministic test sequences are only designed to test understanding and expected behavior of the CLIC spec.

A PR request has been made at riscv-arch-test: riscv-non-isa/riscv-arch-test#436

2.1. smclic testcases

smclic testcases work for implementations that support m-mode.

generic test pseudo code that is used by most clic tests to stimulate different behavior. anything in ALL_CAPS are defines that can be overwritten with -D or at top of test or in model_test.h

/* to stimulate different test behavior using the same generic test pseudo code,
   individual tests will #define different default values here */

#include "model_test.h"
#include "arch_test.h"

current mtvec/mscratch saved (used by arch_test.h so needs to be restored at end of test)

RVMODEL_SETUP_CLIC /* hook to allow implementations to setup their setup required for their specific CLIC implementation (num priv modes, num interrupt levels) */
program mintthresh to RVMODEL_MINTTHRESH
program interrupt1 CLICINTCTL/CLICINTATTR values (based on RVMODEL_INT1_EXCCODE, RVMODEL_INT1_CLICINTCTL, RVMODEL_INT1_CLICINTATTR defines)
program interrupt2 CLICINTCTL/CLICINTATTR values (based on RVMODEL_INT2_EXCCODE, RVMODEL_INT2_CLICINTCTL, RVMODEL_INT2_CLICINTATTR defines)
program interrupt1/2 CLICINTIE (based on RVMODEL_INT1_CLICINTIE, RVMODEL_INT2_CLICINTIE)
RVMODEL_SET_INT1
fence
switch priv_mode to RVMODEL_CLIC_STARTING_PRIV
set mstatus.mie to RVMODEL_MSTATUS_MIE
RVMODEL_WFI
finish /* e.g. if RVMODEL_SET_INT1 is defined to actually not set interrupt1, or interrupt level is 0, or interrupt priv is < current_priv), all signatures would stay default */

m_interrupt_handler1:
  save signatures /* mcause, mstatus, mepc, mtval, mintstatus, mintthresh, mnxti, mscratch, mscratchcsw, mscratchcswl */
  modify mtvec/mtvt to point to interrupt handler2:
  RVMODEL_CLEAR_INT1
  RVMODEL_SET_INT2
  csrrsi t0, mnxti RVMODEL_MNXTI_SIMMED
  set mstatus.mie to RVMODEL_MSTATUS_MIE /* e.g. if RVMODEL_CLEAR_INT1 was defined to actually not clear interrupt1, interrupt1 is still asserted, clint would preempt and jump to interrupt handler2, clic does not */
  modify mepc to jump to finsh
  csrrci t0, mnxti RVMODEL_MNXTI_CIMMED
  save signatures /* mcause, mstatus, mepc, mtval, mintstatus, mintthresh, mnxti, mscratch, mscratchcsw, mscratchcswl */
  mret

m_interrupt_handler2:
  save signatures /* mcause, mstatus, mepc, mtval, mintstatus, mintthresh, mnxti, mscratch, mscratchcsw, mscratchcswl */
  RVMODEL_CLEAR_INT2
  clear mstatus.mpie (so mstatus.mie is 0 after mret)
  mret

finish:
restore mtvec, mscratch for arch_test.h

smclic tests TEST PLAN CASES Defaults:

RVMODEL_INT1_EXCCODE = 0
RVMODEL_INT2_EXCCODE = 3
RVMODEL_INT1_CLICINTIE = 1
RVMODEL_INT2_CLICINTIE = 1
RVMODEL_MSTATUS_MIE = 1
RVMODEL_MNXTI_SIMMED = 0x8
RVMODEL_MNXTI_CIMMED = 0x8
RVMODEL_WFI nop

2.1.1. clicnomint-01.S

Description: expect interrupts will not trigger in m-mode unless mstatus.mie is set
  • enable clicintie (default)

  • generate interrupt1

  • nop

  • jump to finish

 RVMODEL_MSTATUS_MIE = 0
 RVMODEL_SET_INT1 = RVMODEL_SET_MSW_INT
 RVMODEL_SET_INT2 = RVMODEL_SET_MTIMER_INT
 RVMODEL_CLEAR_INT1 = RVMODEL_CLEAR_MSW_INT
 RVMODEL_CLEAR_INT2 = RVMODEL_CLEAR_MTIMER_INT
 RVMODEL_WFI = nop

Coverage

mstatus.mie | verify no interrupt occurs in m-mode if mstatus.mie is 0

2.1.2. clicnomint-02.S

Description: expect interrupts will not trigger in m-mode unless clicintie.x is set
  • disable clicintie

  • generate interrupt1

  • enable mstatus.mie

  • nop

  • jump to finish

 RVMODEL_INT1_CLICINTIE = 0
 RVMODEL_INT2_CLICINTIE = 0
 RVMODEL_SET_INT1 = RVMODEL_SET_MSW_INT
 RVMODEL_SET_INT2 = RVMODEL_SET_MTIMER_INT
 RVMODEL_CLEAR_INT1 = RVMODEL_CLEAR_MSW_INT
 RVMODEL_CLEAR_INT2 = RVMODEL_CLEAR_MTIMER_INT
 RVMODEL_WFI = nop

Coverage

clicintie[msw]    | verify no msw interrupt occurs if clicintie[msw] is 0
clicintie[mtimer] | verify no mtimer interrupt occurs if clicintie[mtimer] is 0

2.1.3. clicnomint-03.S

Description: expect interrupts will not trigger in m-mode unless clicintctrl.x > mintthresh
  • enable clicintie (default)

  • generate interrupt1

  • enable mstatus.mie

  • nop

  • jump to finish

 RVMODEL_MINTTHRESH = RVMODEL_MINTTHRESH_MAX
 RVMODEL_SET_INT1 = RVMODEL_SET_MSW_INT
 RVMODEL_SET_INT2 = RVMODEL_SET_MTIMER_INT
 RVMODEL_CLEAR_INT1 = RVMODEL_CLEAR_MSW_INT
 RVMODEL_CLEAR_INT2 = RVMODEL_CLEAR_MTIMER_INT
 RVMODEL_WFI = nop

Coverage

mintthresh    | verify no msw interrupt occurs if mintthresh is max

2.1.4. clicwfi-01.S

Description: expect wfi to behave like a nop when a single interrupt is pending when mstatus.mie is disabled
  • enable clicintie (default)

  • generate interrupt1

  • wfi

  • wakeup

  • jump to finish

 RVMODEL_MSTATUS_MIE = 0
 RVMODEL_SET_INT1 = RVMODEL_SET_MSW_INT
 RVMODEL_SET_INT2 = RVMODEL_SET_MSW_INT
 RVMODEL_CLEAR_INT1 = RVMODEL_CLEAR_MSW_INT
 RVMODEL_CLEAR_INT2 = RVMODEL_CLEAR_MSW_INT

Coverage

mstatus.mie | verify no interrupt occurs in m-mode if mstatus.mie is 0
wfi | verify wakeup/nop occurs with mstatus.mie = 0
wfi | verify wakeup/nop occurs with pending interrupt

2.1.5. clicdirect-01.S

Description: trigger, clear, no retrigger of same interrupt. Will hang if no interrupt occurs
  • enable clicintie (default)

  • generate interrupt1

  • enable mstatus.mie

  • trigger m-mode handler

  • clear 1st interrupt

  • generate interrupt1 again (ignored)

  • set mepc to finish

  • mret to finish

 RVMODEL_SET_INT1 = RVMODEL_SET_MSW_INT
 RVMODEL_SET_INT2 = RVMODEL_SET_MSW_INT
 RVMODEL_CLEAR_INT1 = RVMODEL_CLEAR_MSW_INT
 RVMODEL_CLEAR_INT2 = RVMODEL_CLEAR_MSW_INT
 RVMODEL_MINTTHRESH = RVMODEL_MINTTHRESH_MIN
 RVMODEL_WFI = jump_to_self

Coverage

mtvec.mode     | verify direct mode is used to handle interrupt
no msip retrigger | verify after mstatus.mie is enabled in interrupt handler, msip will not retrigger because msip intlevel is not > mintstatus
msip trigger | verify RVMODEL_SET_MSW_INT trigger
msip clear   | verify RVMODEL_CLEAR_MSW_INT clear
mcause       | verify machine software interrupt signature
mstatus      | verify mstatus.mie/mpie/mpp signature in interrupt handler and after mret
mtvec        | verify interrupt uses mtvec to calculate pc of interrupt handler (direct)
mepc         | verify mepc location is jump_to_self location

2.1.6. cliclevel-01.S

Description: verify interrupt level order, 2 interrupts asserted in 1st interrupt handler, min level int followed by max level int
  • enable clicintie (default)

  • generate interrupt 1

  • enable mstatus.mie

  • trigger m-mode handler

  • generate interrupt 2 (both interrupts now pending)

  • if clicintctrl represents levels, mnxti csrrsi updates mcause.id for 2nd interrupt

  • if clicintctrl represents priority, no 2nd interrupt occurs.

  • set mepc to finish

  • clear mstatus.mpie

  • mret to finish

 RVMODEL_SET_INT1 = RVMODEL_SET_MSW_INT
 RVMODEL_SET_INT2 = RVMODEL_SET_MTIMER_INT
 RVMODEL_CLEAR_INT1 = <EMPTY>
 RVMODEL_CLEAR_INT2 = RVMODEL_CLEAR_MTIMER_INT
 RVMODEL_INT1_CLICINTCTL = RVMODEL_CLICINTCTL_MIN
 RVMODEL_INT2_CLICINTCTL = RVMODEL_CLICINTCTL_MAX

Coverage

Interrupt ordering - both interrupts asserted in first interrupt handler

2.1.7. cliclevel-02.S

Description: verify interrupt level order, 2 interrupts asserted in 1st interrupt handler, min level int followed by max level int
  • enable clicintie (default)

  • generate interrupt 1

  • enable mstatus.mie

  • trigger m-mode handler

  • generate interrupt 2 (both interrupts now pending)

  • if clicintctrl represents levels, trigger 2nd m-mode handler

  • if clicintctrl represents priority, no 2nd interrupt occurs.

  • set mepc to finish

  • clear mstatus.mpie

  • mret to finish

 RVMODEL_SET_INT1 = RVMODEL_SET_MSW_INT
 RVMODEL_SET_INT2 = RVMODEL_SET_MTIMER_INT
 RVMODEL_CLEAR_INT1 = <EMPTY>
 RVMODEL_CLEAR_INT2 = RVMODEL_CLEAR_MTIMER_INT
 RVMODEL_INT1_CLICINTCTL = RVMODEL_CLICINTCTL_MIN
 RVMODEL_INT2_CLICINTCTL = RVMODEL_CLICINTCTL_MAX
 RVMODEL_MNXTI_SIMMED = 0

Coverage

Interrupt ordering - both interrupts asserted in first interrupt handler

2.1.8. cliclevel-03.S

Description: verify interrupt level order, 2 interrupts asserted in 1st interrupt handler, max level int followed by min level int
  • enable clicintie (default)

  • generate interrupt 1

  • enable mstatus.mie

  • trigger m-mode handler

  • generate interrupt 2 (both interrupts now pending)

  • if clicintctrl represents levels, 2nd interrupt is lower than current interupt level, no 2nd interrupt occurs.

  • if clicintctrl represents priority, 2nd interrupt is same level, no 2nd interrupt occurs.

  • set mepc to finish

  • clear mstatus.mpie

  • mret to finish

 RVMODEL_SET_INT1 = RVMODEL_SET_MSW_INT
 RVMODEL_SET_INT2 = RVMODEL_SET_MTIMER_INT
 RVMODEL_CLEAR_INT1 = <EMPTY>
 RVMODEL_CLEAR_INT2 = RVMODEL_CLEAR_MTIMER_INT
 RVMODEL_INT1_CLICINTCTL = RVMODEL_CLICINTCTL_MAX
 RVMODEL_INT2_CLICINTCTL = RVMODEL_CLICINTCTL_MIN

Coverage

Interrupt ordering - both interrupts asserted in first interrupt handler

2.1.9. cliclevel-04.S

Description: verify interrupt level order, 2 interrupts asserted in 1st interrupt handler, min level int followed by max level int with max mintthresh setting.
  • enable clicintie (default)

  • generate interrupt 1

  • enable mstatus.mie

  • trigger m-mode handler

  • generate interrupt 2 (both interrupts now pending)

  • if clicintctrl represents levels, 2nd interrupt is higher than current interupt level but equal to mintthresh, no 2nd interrupt occurs.

  • if clicintctrl represents priority, 2nd interrupt is same level, no 2nd interrupt occurs.

  • set mepc to finish

  • clear mstatus.mpie

  • mret to finish

 RVMODEL_SET_INT1 = RVMODEL_SET_MSW_INT
 RVMODEL_SET_INT2 = RVMODEL_SET_MTIMER_INT
 RVMODEL_CLEAR_INT1 = <EMPTY>
 RVMODEL_CLEAR_INT2 = RVMODEL_CLEAR_MTIMER_INT
 RVMODEL_INT1_CLICINTCTL = RVMODEL_CLICINTCTL_MIN
 RVMODEL_INT2_CLICINTCTL = RVMODEL_CLICINTCTL_MAX
 RVMODEL_MINTTHRESH_HNDLR1 = RVMODEL_MINTTHRESH_MAX

Coverage

Interrupt ordering - both interrupts asserted in first interrupt handler

2.2. ssclic testcases

2.2.1. sclicnodeleg-01.S

Description: Verify when executing in s-mode, the m-mode interrupt will be handled even though mstatus.mie is 0:
  • generate m-mode interrupt (msw)

  • switch to s-mode (mstatus.mie disabled),

  • trigger (m-mode handler),

  • clear interrupt,

  • return to s-mode,

  • ecall back to m-mode

 RVMODEL_MSTATUS_MIE    = 0
 RVMODEL_SET_MINT1      = RVMODEL_SET_MSW_INT;
 RVMODEL_CLEAR_MINT1    = RVMODEL_CLEAR_MSW_INT;
 RVMODEL_MINTTHRESH     = RVMODEL_MINTTHRESH_MAX

Coverage

clicintattr[msw].mode == 11 | verify interrupt is handled in m-mode
mstatus.mie=0     | verify m-mode interrupt will occur in s-mode when mstatus.mie=0
mcause signature  | verify msw cause signature

2.2.2. sclicdeleg-01.S

Description: Verify when executing in s-mode, an s-mode interrupt will be handled when mstatus.sie is 1:
  • generate s-mode interrupt (sint1),

  • switch to s-mode,

  • trigger (s-mode handler),

  • clear interrupt,

  • ecall back to m-mode

 RVMODEL_MSTATUS_MIE       = MSTATUS_SIE
 RVMODEL_SINT1_CLICINTATTR = RVMODEL_CLICINTATTR_SMODE
 RVMODEL_SET_SINT1         = RVMODEL_SET_MSW_INT
 RVMODEL_CLEAR_SINT1       = RVMODEL_CLEAR_MSW_INT
 RVMODEL_SINT1_EXCCODE     = 0x3

Coverage

clicintattr[sint1].mode == 01          | verify interrupt is handled in s-mode
mstatus.sie=1     | verify s-mode interrupt will occur in s-mode when mstatus.sie=1
scause signature  | verify msw signature
mcause signature  | verify ecall signature

2.2.3. sclicorder-01.S

Description: Verify order of 2 s-mode interrupts
  • generate 2 s-mode interrupts (msw, mtimer),

  • switch to s-mode,

  • trigger (s-mode handler),

  • clear interrupts,

  • ecall back to m-mode

 RVMODEL_MSTATUS_MIE       = MSTATUS_SIE
 RVMODEL_SINT1_CLICINTATTR = RVMODEL_CLICINTATTR_SMODE
 RVMODEL_SET_SINT1         = RVMODEL_SET_MSW_INT
 RVMODEL_CLEAR_SINT1       = RVMODEL_CLEAR_MSW_INT
 RVMODEL_SINT2_CLICINTATTR = RVMODEL_CLICINTATTR_SMODE
 RVMODEL_SET_SINT2         = RVMODEL_SET_MTIMER_INT
 RVMODEL_CLEAR_SINT2       = RVMODEL_CLEAR_MTIMER_INT
 RVMODEL_SINT1_CLICINTCTL  = RVMODEL_CLICINTCTL_MAX
 RVMODEL_SINT2_CLICINTCTL  = RVMODEL_CLICINTCTL_MIN
 RVMODEL_SINT1_EXCCODE     = 0x3
 RVMODEL_SINT2_EXCCODE     = 0x7

Coverage

scause signature  | verify priority of int1/int2

2.2.4. sclicorder-02.S

Description:
  • generate 2 s-mode interrupts (msw, mtimer),

  • switch to s-mode,

  • trigger (s-mode handler),

  • only sint1 is cleared,

  • re-enable mstatus.sie

  • trigger (go to stvec_finish, capture cause signature)

  • ecall back to m-mode

 RVMODEL_MSTATUS_MIE       = MSTATUS_SIE
 RVMODEL_SINT1_CLICINTATTR = RVMODEL_CLICINTATTR_SMODE
 RVMODEL_SET_SINT1         = RVMODEL_SET_MSW_INT
 RVMODEL_CLEAR_SINT1       = RVMODEL_CLEAR_MSW_INT
 RVMODEL_SINT2_CLICINTATTR = RVMODEL_CLICINTATTR_SMODE
 RVMODEL_SET_SINT2         = RVMODEL_SET_MTIMER_INT
 RVMODEL_SINT1_CLICINTCTL  = RVMODEL_CLICINTCTL_MAX
 RVMODEL_SINT2_CLICINTCTL  = RVMODEL_CLICINTCTL_MIN
 RVMODEL_SINT1_EXCCODE     = 0x3
 RVMODEL_SINT2_EXCCODE     = 0x7
 RVMODEL_CLEAR_SSTATUS_SPIE = 0

Coverage - same as order-01.S except

scause 2nd signature | verify sti occurs after ssi cleared and sret

2.2.5. sclicorder-03.S

Description:
  • generate 2 s-mode interrupts (msw, mtimer),

  • switch to s-mode,

  • trigger (s-mode handler),

  • only sint1 is cleared,

  • set sintthresh

  • re-enable mstatus.sie

  • ecall back to m-mode

 RVMODEL_MSTATUS_MIE       = MSTATUS_SIE
 RVMODEL_SINT1_CLICINTATTR = RVMODEL_CLICINTATTR_SMODE
 RVMODEL_SET_SINT1         = RVMODEL_SET_MSW_INT
 RVMODEL_CLEAR_SINT1       = RVMODEL_CLEAR_MSW_INT
 RVMODEL_SINT2_CLICINTATTR = RVMODEL_CLICINTATTR_SMODE
 RVMODEL_SET_SINT2         = RVMODEL_SET_MTIMER_INT
 RVMODEL_SINT1_CLICINTCTL  = RVMODEL_CLICINTCTL_MAX
 RVMODEL_SINT2_CLICINTCTL  = RVMODEL_CLICINTCTL_MIN
 RVMODEL_SINTTHRESH_HNDLR1 = RVMODEL_SINTTHRESH_MAX
 RVMODEL_SINT1_EXCCODE     = 0x3
 RVMODEL_SINT2_EXCCODE     = 0x7
 RVMODEL_CLEAR_SSTATUS_SPIE = 0

Coverage - same as order-01.S except

scause 2nd signature | verify sti only occurs after ssi cleared and sret if sti level > sintthresh

2.2.6. sclicorder-04.S

Description:
  • generate 2 s-mode interrupts (msw, mtimer),

  • switch to s-mode,

  • trigger (s-mode handler),

  • only sint2 is cleared,

  • re-enable mstatus.sie

  • trigger (go to stvec_finish, capture cause signature)

  • ecall back to m-mode

 RVMODEL_MSTATUS_MIE       = MSTATUS_SIE
 RVMODEL_SINT1_CLICINTATTR = RVMODEL_CLICINTATTR_SMODE
 RVMODEL_SET_SINT1         = RVMODEL_SET_MSW_INT
 RVMODEL_SINT2_CLICINTATTR = RVMODEL_CLICINTATTR_SMODE
 RVMODEL_SET_SINT2         = RVMODEL_SET_MTIMER_INT
 RVMODEL_CLEAR_SINT2       = RVMODEL_CLEAR_MTIMER_INT
 RVMODEL_SINT1_CLICINTCTL  = RVMODEL_CLICINTCTL_MAX
 RVMODEL_SINT2_CLICINTCTL  = RVMODEL_CLICINTCTL_MIN
 RVMODEL_SINT1_EXCCODE     = 0x3
 RVMODEL_SINT2_EXCCODE     = 0x7
 RVMODEL_CLEAR_SSTATUS_SPIE = 0

Coverage - verify uncleared ssi interrupt will retrigger after sret

scause 2nd signature | verify 2nd signature

2.2.7. sclicprivorder-01.S

Description: Verify m-mode interrupt is handled before s-mode interrupt
  • generate 1 m-mode interrupt (mtimer) and 1 s-mode interrupt (msw),

  • switch to s-mode,

  • trigger (m-mode handler),

  • clear m-mode interrupt

  • return to s-mode

  • trigger (s-mode handler)

  • clear s-mode interrupt

  • return to s-mode

  • ecall back to m-mode

 RVMODEL_MSTATUS_MIE       = MSTATUS_SIE
 RVMODEL_SINT1_CLICINTATTR = RVMODEL_CLICINTATTR_SMODE
 RVMODEL_SET_SINT1         = RVMODEL_SET_MSW_INT
 RVMODEL_CLEAR_SINT1       = RVMODEL_CLEAR_MSW_INT
 RVMODEL_MINT2_CLICINTATTR = RVMODEL_CLICINTATTR_MMODE
 RVMODEL_SET_MINT2         = RVMODEL_SET_MTIMER_INT
 RVMODEL_CLEAR_MINT2       = RVMODEL_CLEAR_MTIMER_INT
 RVMODEL_SINT1_CLICINTCTL  = RVMODEL_CLICINTCTL_MAX
 RVMODEL_MINT2_CLICINTCTL  = RVMODEL_CLICINTCTL_MIN
 RVMODEL_SINT1_EXCCODE     = 0x3
 RVMODEL_MINT2_EXCCODE     = 0x7

Coverage - same as order-04.S except

mcause 1st signature | verify m-mode int 1st signature
scause 2nd signature | verify s-mode int 2nd signature

2.2.8. sclicprivorder-02.S

Description: Verify m-mode interrupt is handled before s-mode interrupt setting sintthresh to max
  • generate 1 m-mode interrupt (mtimer) and 1 s-mode interrupt (msw),

  • switch to s-mode,

  • trigger (m-mode handler),

  • clear m-mode interrupt

  • return to s-mode

  • trigger (s-mode handler)

  • clear s-mode interrupt

  • return to s-mode

  • ecall back to m-mode

 RVMODEL_MSTATUS_MIE       = MSTATUS_SIE
 RVMODEL_SINT1_CLICINTATTR = RVMODEL_CLICINTATTR_SMODE
 RVMODEL_SET_SINT1         = RVMODEL_SET_MSW_INT
 RVMODEL_CLEAR_SINT1       = RVMODEL_CLEAR_MSW_INT
 RVMODEL_MINT2_CLICINTATTR = RVMODEL_CLICINTATTR_MMODE
 RVMODEL_SET_MINT2         = RVMODEL_SET_MTIMER_INT
 RVMODEL_CLEAR_MINT2       = RVMODEL_CLEAR_MTIMER_INT
 RVMODEL_SINT1_CLICINTCTL  = RVMODEL_CLICINTCTL_MAX
 RVMODEL_MINT2_CLICINTCTL  = RVMODEL_CLICINTCTL_MIN
 RVMODEL_SINTTHRESH_HNDLR1 = RVMODEL_SINTTHRESH_MAX
 RVMODEL_SINT1_EXCCODE     = 0x3
 RVMODEL_MINT2_EXCCODE     = 0x7

Coverage

mcause 1st signature | verify m-mode int 1st signature
scause 2nd signature | verify s-mode int 2nd signature

2.2.9. sclicprivorder-03.S

Description: Verify m-mode interrupt is handled before s-mode interrupt setting mintthresh to max
  • generate 1 m-mode interrupt (mtimer) and 1 s-mode interrupt (msw),

  • switch to s-mode,

  • trigger (m-mode handler),

  • clear m-mode interrupt

  • return to s-mode

  • trigger (s-mode handler)

  • clear s-mode interrupt

  • return to s-mode

  • ecall back to m-mode

 RVMODEL_MSTATUS_MIE       = MSTATUS_SIE
 RVMODEL_SINT1_CLICINTATTR = RVMODEL_CLICINTATTR_SMODE
 RVMODEL_SET_SINT1         = RVMODEL_SET_MSW_INT
 RVMODEL_CLEAR_SINT1       = RVMODEL_CLEAR_MSW_INT
 RVMODEL_MINT2_CLICINTATTR = RVMODEL_CLICINTATTR_MMODE
 RVMODEL_SET_MINT2         = RVMODEL_SET_MTIMER_INT
 RVMODEL_CLEAR_MINT2       = RVMODEL_CLEAR_MTIMER_INT
 RVMODEL_SINT1_CLICINTCTL  = RVMODEL_CLICINTCTL_MAX
 RVMODEL_MINT2_CLICINTCTL  = RVMODEL_CLICINTCTL_MIN
 RVMODEL_MINTTHRESH_HNDLR1 = RVMODEL_MINTTHRESH_MAX
 RVMODEL_SINT1_EXCCODE     = 0x3
 RVMODEL_MINT2_EXCCODE     = 0x7

Coverage

mcause 1st signature | verify m-mode int 1st signature
scause 2nd signature | verify s-mode int 2nd signature

2.2.10. sclicmdisable-01.S

Description: Verify m-mode interrupt not taken in m-mode when mstatus.mie is 0
  • generate m-mode interrupt (msw)

  • stay in m-mode

  • wfi

  • wakeup

  • jump to done

  • ecall

 RVMODEL_SWITCH_TO_S_MODE  = <EMPTY>
 RVMODEL_MSTATUS_MIE       = 0
 RVMODEL_MINT1_CLICINTATTR = RVMODEL_CLICINTATTR_MMODE
 RVMODEL_SET_MINT1         = RVMODEL_SET_MSW_INT
 RVMODEL_CLEAR_MINT1       = RVMODEL_CLEAR_MSW_INT
 RVMODEL_MINT1_EXCCODE     = 0x3

Coverage

mstatus.mie  | verify no m-mode interrupt taken when in m-mode and clicintie is 0

2.2.11. sclicmdisable-02.S

Description: Verify m-mode interrupt not taken in m-mode when clicintie is 0
  • generate m-mode interrupt (msw)

  • stay in m-mode

  • nop

  • wakeup

  • jump to done

  • ecall

 RVMODEL_WFI               = nop
 RVMODEL_SWITCH_TO_S_MODE  = <EMPTY>
 RVMODEL_MSTATUS_MIE       = MSTATUS_MIE
 RVMODEL_MINT1_CLICINTIE   = 0x0
 RVMODEL_MINT1_CLICINTATTR = RVMODEL_CLICINTATTR_MMODE
 RVMODEL_SET_MINT1         = RVMODEL_SET_MSW_INT
 RVMODEL_CLEAR_MINT1       = RVMODEL_CLEAR_MSW_INT
 RVMODEL_MINT1_EXCCODE     = 0x3

Coverage

clicintie=0  | verify m-mode interrupt not taken when in m-mode and clicintie is 0

2.2.12. sclicmdisable-03.S

Description: Verify s-mode interrupt not taken in m-mode
  • generate s-mode interrupt (msw)

  • stay in m-mode

  • wfi

  • wakeup

  • jump to done

  • ecall

 RVMODEL_SWITCH_TO_S_MODE = <EMPTY>
 RVMODEL_SINT1_CLICINTATTR = RVMODEL_CLICINTATTR_SMODE
 RVMODEL_SET_SINT1         = RVMODEL_SET_MSW_INT
 RVMODEL_CLEAR_SINT1       = RVMODEL_CLEAR_MSW_INT
 RVMODEL_SINT1_EXCCODE     = 0x3

Coverage

mstatus.sie=1  | verify s-mode interrupt not taken when in m-mode

2.2.13. sclicsdisable-01.S

Description: Verify s-mode interrupt not taken in s-mode when mstatus.sie is 0
  • generate s-mode interrupt (msw)

  • switch to s-mode,

  • wfi

  • wakeup

  • jump to done

  • ecall back to m-mode

 RVMODEL_MSTATUS_SIE       = 0
 RVMODEL_SINT1_CLICINTATTR = RVMODEL_CLICINTATTR_SMODE
 RVMODEL_SET_SINT1         = RVMODEL_SET_MSW_INT
 RVMODEL_CLEAR_SINT1       = RVMODEL_CLEAR_MSW_INT
 RVMODEL_SINT1_EXCCODE     = 0x3

Coverage

mstatus.mie=1, mstatus.sie=0  | verify s-mode interrupt not taken when in s-mode when mstatus.sie is 0

2.2.14. sclicsdisable-02.S

Description: Verify s-mode interrupt not taken in s-mode when clcintie is 0
  • generate s-mode interrupt (msw)

  • switch to s-mode,

  • nop

  • jump to done

  • ecall back to m-mode

 RVMODEL_WFI               = nop
 RVMODEL_MSTATUS_MIE       = MSTATUS_SIE
 RVMODEL_SINT1_CLICINTIE   = 0x0
 RVMODEL_SINT1_CLICINTATTR = RVMODEL_CLICINTATTR_SMODE
 RVMODEL_SET_SINT1         = RVMODEL_SET_MSW_INT
 RVMODEL_CLEAR_SINT1       = RVMODEL_CLEAR_MSW_INT
 RVMODEL_SINT1_EXCCODE     = 0x3

Coverage

sie=0  | verify s-mode interrupt not taken when in s-mode when clicintie=0

2.2.15. sclicsdisable-03.S

Description: Verify s-mode interrupt not taken in m-mode when mstatus.sie is 1 (but wfi acts as nop)
  • generate s-mode interrupt (msw)

  • wfi

  • wakeup

  • jump to done

 RVMODEL_SWITCH_TO_S_MODE  = <EMPTY>
 RVMODEL_MSTATUS_MIE       = MSTATUS_SIE
 RVMODEL_SINT1_CLICINTATTR = RVMODEL_CLICINTATTR_SMODE
 RVMODEL_SET_SINT1         = RVMODEL_SET_MSW_INT
 RVMODEL_CLEAR_SINT1       = RVMODEL_CLEAR_MSW_INT
 RVMODEL_SINT1_EXCCODE     = 0x3

Coverage

mstatus.sie=1, mstatus.sie=1  | verify s-mode interrupt not taken when in m-mode when mstatus.sie is 1

2.2.16. sclicwfi-01.S

Description: expect wfi to behave like a nop when a single interrupt is pending when mstatus.mie is disabled
  • enable clicintie (default)

  • generate s-mode interrupt (msw)

  • wfi

  • wakeup

  • jump to finish

 RVMODEL_MSTATUS_MIE = 0
 RVMODEL_SET_SINT1 = RVMODEL_SET_MSW_INT
 RVMODEL_CLEAR_INT1 = RVMODEL_CLEAR_MSW_INT
 RVMODEL_SINT1_CLICINTATTR = RVMODEL_CLICINTATTR_SMODE
 RVMODEL_SINT1_EXCCODE     = 0x3

Coverage

mstatus.mie | verify no interrupt occurs in m-mode if mstatus.mie is 0
wfi | verify wakeup/nop occurs with mstatus.mie = 0
wfi | verify wakeup/nop occurs with pending interrupt

2.3. smclicshv testcases

TEST PLAN CASES

verify shv auto-clears an edge triggered interrupt
verify shv interrupt is handled at the correct index in the xtvt table
verify exception is taken when xtvt table is in non-executable region
verify scause.sinhv set with mret returning to s-mode treats mepc as addr in xtvt table

2.4. Coverage

Coverage Holes

  • async behavior on pipeline

    • Tests only have interrupts occur after mstatus.mie enabled or mret (which sets mstatus.mie to mstatus.mpie)

  • limited interrupt types tested

    • Tests only compare up-to two interrupts at a time.

    • Only msw and mtimer interrupts are used. MSW and Mtimer interrupts are only asserted and cleared by macros so no actual checking of CLINT msw and mtimer behavior is checked. E.g. No mtimer overflow, increment, mtimer/mtimerh rollover is checked. No external interrupts (SEI, MEI) checked by default. can be overridden with define.

  • clicintattr.trig is not testied, i.e., edge vs. level interrupts aren’t tested. interrupt positive-edge vs. negative-edge is not tested.

  • xtvec locations

    • Locations aren’t randomized, range of table jumps aren’t randomized

    • Handler address is always in executable memory so no exceptions will occur during interrupt.

  • interrupts vs. exceptions

    • Only ecall exceptions are used to verify mcause.interrupt toggling.

  • wfi holes

    • wfi only confirmed to continue/wakeup when mstatus.mie is 0. Interrupts occur before wfi but do not occur while executing wfi.

    • situations where wfi is not required to wake up are not tested

    • wfi resume after interrupt is not checked

    • wfi priv-mode traps not checked

  • WARL settings of implementation

    • Only legal values are intended to be written to CSRs. WARL behavior is not checked.

  • No u-mode interrupts checked