Skip to content

[ACT] ACTs and coverage points for machine mode software and timer interrupts #567

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 32 commits into
base: dev
Choose a base branch
from

Conversation

Ali-Faraz-10xe
Copy link

@Ali-Faraz-10xe Ali-Faraz-10xe commented Nov 21, 2024

Description

This pull request introduces tests and covergroups to verify machine mode software and timer interrupts. The tests and covergroups were developed following the guidelines outlined in the Test Plan

Related Issues

This pull request relies on the changes in the following PRs for full functionality and compatibility:

  1. Interrupt Coverage Support
  2. Print MTI value upon hart update for machine timer interrupt visibility

Ratified/Unratified Extensions

  • Ratified
  • Unratified

List Extensions

N/A

Reference Model Used

  • SAIL
  • Spike
  • Other - < SPECIFY HERE >

DUT Model Used

  • SAIL
  • Spike
  • Other - < SPECIFY HERE >

Mandatory Checklist:

  • All tests are compliant with the test-format spec present in this repo ?
  • Ran the new tests on RISCOF with SAIL/Spike as reference model successfully ?
  • Ran the new tests on RISCOF in coverage mode
  • Link to Google-Drive folder containing the new coverage reports available here
  • Link to PR in RISCV-ISAC from which the reports were generated available here

Optional Checklist:

  • Were the tests hand-written/modified ?

@jamesbeyond jamesbeyond changed the title ACTs and coverage points for machine mode software and timer interrupts [ACT] ACTs and coverage points for machine mode software and timer interrupts Dec 2, 2024
Copy link
Collaborator

@allenjbaum allenjbaum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, equations with constants (e.g. mip>>3 & 0x1!= 0x1) are not satisfactory. What would be satisfactory would be ((mip & MIP_MSIP)==0), where MIP_MSIP is #defined - and you don't even have to define it yourself because it is already defined in encoding.h which is #included. Note that this applies of almost CSR fields . The comments are quite appreciated, on the other hand.

Copy link
Collaborator

@allenjbaum allenjbaum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost all tests need to initialize MIP.MSIP/MTIP before doing anything else.
The MAX_VALE should be renamed TEST_VALUE, since it isn't a max value at all.
I think you could combine a lot of the 32 and 64b tests, except for the cases that need to write all 64bits of MTIME and MTiMECMP (which I would do with a macro to and read them differently depending on XLEN)

@Ali-Faraz-10xe Ali-Faraz-10xe force-pushed the m_interrupts branch 3 times, most recently from d1bcf98 to d4efbfb Compare April 9, 2025 12:32
@Ali-Faraz-10xe Ali-Faraz-10xe force-pushed the m_interrupts branch 2 times, most recently from 70d8faf to 6a00d29 Compare April 9, 2025 12:40
Copy link
Collaborator

@UmerShahidengr UmerShahidengr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All requested changes have been done

Copy link
Collaborator

@allenjbaum allenjbaum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the first batch of overall changes that are needed. I'll come back and do another review when these are fixed (I haven't made it all the way through yet.

sv_\__MODE__\()ip: // note: clear has no effect on MxIP
SREG T4, 2*REGWIDTH(T1) // save 3rd sig value, (xip)
csrrc T2, CSR_MIDELEG, x0 // read machine interrupt delegation
nop // if mideleg is not used and trap occur
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to document the reason for this. This is setting up the trap handler to take an exception whenever it interrupts into Smode (because it can't read the mideleg CSR that caused it to go to Smode?)
The problem here is that the trap signature for an illegal instruction won't store mideleg - so the test can never tell whether mideleg was set or not. It would be best to have the test (not the trap handler) explicitly store mideleg whenever it changes it, and avoid the extra trap.

srl T4, T4, T2 // move xIE to LSB
andi T4, T4, 0b10001 // mask xIE and xPIE
SREG T4, 2*REGWIDTH(T1) // save 3rd sig value, (xstatus.XIE and xstatus.XPIE)
nop
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is there a nop here? This shouldn't ever trap. Also: you're storing individual bits from Xstatus, XIE, and XIP; you should collect the 3 bits and store them in the first signature entry, (label sv__MODE_()vect, the first word of the signature entry; there are lots of free bits in that entry. This avoids changing the size of the interrupt trap signature entry. That size is pre-calculated, is used to update the trap signature pointer, and is stored in this entry. Changing the size introduces a bug because the pointer is pre-incremented with it, and the next trap will overwrite the extra word of this entry.

val_comb:
# Verify MSIP set and clear mechanisms
'(call_type != "interrupt") and ((mstatus & ${MSTATUS_MIE}) == 0) and ((mip & ${MIP_MSIP}) == ${MIP_MSIP})' : 0 # Checks software interrupt pending mechanism when writing 1 to memory-mapped MSIP control register without immediate interrupt service.
'(call_type != "interrupt") and ((mstatus & ${MSTATUS_MIE}) == 0) and ((mip & ${MIP_MSIP}) == 0)' : 0 # Validates software interrupt clearing mechanism when writing 0 to memory-mapped MSIP control register.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one will get hit right out of reset. This needs to be conditioned on the old value of MIP_MSIP

val_comb:
# Verify MTIP set and clear mechanisms
'(call_type != "interrupt") and ((mstatus & ${MSTATUS_MIE}) == 0) and ((mip & ${MIP_MTIP}) == ${MIP_MTIP})' : 0 # Verifies Machine Timer Interrupt Pending (MTIP) bit setting mechanism during non-interrupt execution.
'(call_type != "interrupt") and ((mstatus & ${MSTATUS_MIE}) == 0) and ((mip & ${MIP_MTIP}) == 0)' : 0 # Checks MTIP bit clearing mechanism when no interrupt is being processed.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will generate false positives unless you can check for edges rather than levels, i.e. mip=MTIP and old_mip!=MTIP

csrrc: 0
sw : 0
val_comb:
'(call_type != "interrupt") and ((mstatus & ${MSTATUS_MIE}) == 0) and ((mie & ${MIE_MSIE}) == ${MIE_MSIE}) and ((mip & ${MIP_MSIP}) == ${MIP_MSIP})' : 0 # Confirms that no software interrupt is taken when global machine interrupt is disabled, despite local interrupt enable being active.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anytime you are checking for call_type != "interrupt" you'll get false positives; but edge checking in all of them.

mret : 0
val_comb:
# Validate software interrupt handling
'(call_type == "interrupt") and ((mstatus & ${MSTATUS_MPP}) == ${MSTATUS_MPP_M}) and ((mstatus & ${MSTATUS_MPIE}) == ${MSTATUS_MPIE}) and ((mstatus & ${MSTATUS_MIE}) == 0) and ((mcause & ${INTERRUPT_MASK}) == ${CAUSE_M_SOFT_INTR}) and ((mie & ${MIE_MSIE}) == ${MIE_MSIE}) and ((mip & ${MIP_MSIP}) == ${MIP_MSIP})': 0 # Validates software interrupt processing when global machine interrupt is enabled, verifying all required interrupt conditions.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this testing only trapping from Mmode? Don't we also want to test from Umode and Smode? Pretty tricky because you wo't necessarily have access to Mmode registers.

@@ -52,13 +56,32 @@ RVMODEL_DATA_SECTION ;\
//RVTEST_IO_ASSERT_DFPR_EQ
#define RVMODEL_IO_ASSERT_DFPR_EQ(_D, _R, _I)

#define RVMODEL_SET_MSW_INT
#define RVMODEL_SET_MSW_INT ;\
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The RVMODEL_Set/Clr_M/H/Sxxx_INT macros need to be redefined so that the aren't placed inline, but are called as simple subroutines with a JAL, and return to the test with a JR. The should be instantiated (not defined) in model_test.h as they are #defined, but with the name as a label at the start (instead of #define), and a JR at the end with a fixed link register (that tests will have to accomodate).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants