Skip to content
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

Add Interrupt and timer support #2

Closed
wants to merge 10 commits into from
11 changes: 11 additions & 0 deletions api/C/include/csi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* Top-level definition file for RVM-CSI API. Note: application writers do not include
* this file: user rvm_csi.h instead.
*/

#ifndef CSI_H
#define CSI_H

#include "csi_interrupts.h"

#endif /* CSI_H */
1 change: 1 addition & 0 deletions api/C/include/csi_bsp_csrs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/* PLACEHOLDER: replaced by content from BSP */
1 change: 1 addition & 0 deletions api/C/include/csi_bsp_defs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/* PLACEHOLDER: replaced by content from BSP */
11 changes: 11 additions & 0 deletions api/C/include/csi_bsp_interrupts.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/* PLACEHOLDER: replaced by content from BSP */

#ifndef CSI_BSP_INTERRUPTS_H
#define CSI_BSP_INTERRUPTS_H

// Context structure for a timeout
typedef struct {
int placeholder;
} csi_timeout_t;

#endif // CSI_BSP_INTERRUPTS_H
1 change: 1 addition & 0 deletions api/C/include/csi_bsp_perip.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/* PLACEHOLDER: replaced by content from BSP */
1 change: 1 addition & 0 deletions api/C/include/csi_csrs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/* PLACEHOLDER: to be replaced by content auto-generated by Sail model */
69 changes: 69 additions & 0 deletions api/C/include/csi_defs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* General-Purpose Definitions for use in CSI code
*
* This file is included from rvm_csi.h prior to all other headers and contains
* general-purpose definitions which may be used by subsequent headers.
*
* Copyright (c) RISC-V International 2022. Creative Commons License. Auto-
* generated file: DO NOT EDIT
*/

#ifndef CSI_DEFS_H
#define CSI_DEFS_H

/*
* Return type for functions indicating status
*/
typedef enum {
CSI_SUCCESS = 0, /* Operation completed successfully */
CSI_NOT_IMPLEMENTED = -1, /* Functionality not implemented */
CSI_ERROR = -2, /* Generic error code */
CSI_NOT_INITIALIZED = -3, /* Sub-system not correctly initialised, operation failed. */
CSI_OUT_OF_MEM = -4, /* Out-of-memory error */
} csi_status_t;

/*
* Enumerates all sources in the system that can give rise to a trap event. This
* enumeration should be treated as an integer which can have additional values
* beyond those enumerated here. A standard set of interrupt and exception sources
* are enumerated here, which exclude external sources. All external interrupt
* sources should be enumerated by the BSP within csi_bsp_interrupts.h; and their
* ennumerated values should follow on from CSI_NUM_STANDARD_TRAP_SOURCES.
* csi_bsp_interrupts.h must also define CSI_TOTAL_BSP_TRAP_SOURCES to indicate the
* total number of sources defined. User applications may then use values above
* this to enumerate user-defined software signals. Note that the actual
* enumerated values have no meaning beyond serving to uniquely identify the source
* of a trap event. They are not intended to map onto values in the mcause
* register.
*/
typedef enum {
CSI_ENUM_NMI = 0, /* Non-maskable exception (hardware error) */
CSI_ENUM_MACHINE_SW_INTERRUPT, /* Machine mode software interrupt */
CSI_ENUM_MACHINE_TIMER_INTERRUPT, /* Machine mode timer interrupt */
CSI_ENUM_INSTRUCTION_ADDR_MISALIGNED_EXCEPTION, /* Instruction misaligned exception */
CSI_ENUM_INSTRUCTION_ACCESS_FAULT_EXCEPTION, /* Instruction access fault exception */
CSI_ENUM_ILLEGAL_INSTRUCTION_EXCEPTION, /* Illegal instruction exception */
CSI_ENUM_BREAKPOINT_EXCEPTION, /* Breakpoint exception */
CSI_ENUM_LOAD_ADDR_MISALIGNED_EXCEPTION, /* Load address misaligned exception */
CSI_ENUM_LOAD_ACCESS_FAULT_EXCEPTION, /* Load access fault exception */
CSI_ENUM_STORE_ADDR_MISALIGNED_EXCEPTION, /* Store address misaligned exception */
CSI_ENUM_STORE_ACCESS_FAULT_EXCEPTION, /* Store access fault exception */
CSI_ENUM_ECALL_FROM_UMODE, /* ECALL from User mode */
CSI_ENUM_ECALL_FROM_MMODE, /* ECALL from Machine mode */
CSI_ENUM_INST_PAGE_FAULT, /* Instruction page-fault */
CSI_ENUM_LOAD_PAGE_FAULT, /* Load page-fault */
CSI_ENUM_STORE_PAGE_FAULT, /* Store page-fault */
CSI_NUM_STANDARD_TRAP_SOURCES, /* Must come last in this list */
} csi_trap_source_t;

Choose a reason for hiding this comment

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

Should trap source classified to interrupt and exception to match mcause.

image

This is how we define in NMSIS Core https://github.com/Nuclei-Software/NMSIS/blob/master/Device/_Template_Vendor/Vendor/Device/Include/Device.h#L64-L114

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

csi_trap_source_t is different from mcause, because it is much more detailed. For example, mcause only has a single entry for "machine external interrrupt", whereas csi_trap_source_t has to enumerate all the external interrupts in the system (the BSP extends it for this purpose). Also, it is useful to have all values of csi_trap_source_t contiguous (without gaps), so that the BSP can maintain a table which is indexed by this enumeration (without wasting memory).

I think there are no efficiency problems here because a decode from mcause (+ PLIC/AIA configuration) to csi_trap_source_t does not need to happen at the time an interrupt is taken (it can happen at the time a handler is registered). csi_trap_source_t just gives a convenient way of indexing sources for the purpose of the HAL API.

Choose a reason for hiding this comment

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

Also, it is useful to have all values of csi_trap_source_t contiguous (without gaps), so that the BSP can maintain a table which is indexed by this enumeration (without wasting memory)

Regarding the contiguous values, I think exception and interrupt should be enumerated in two enum, since exception id and interrupt id could be the same.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sorry I think we have a misunderstanding. The way I conceived it, the actual enumerated values are not important, they don't relate to anything in the hardware. We have a single function (csi_register_m_isr) to register a (machine-mode) user handler for either interrupts or exceptions, so need a single enum.

Choose a reason for hiding this comment

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

OK, so all the handing of the csi_trap_source_t will leave to the implementation of csi_register_m_isr to process this enum.

Copy link

@fanghuaqi fanghuaqi Feb 16, 2023

Choose a reason for hiding this comment

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

And did you take a look at the riscv fast interrupt for mcu, it support vector interrupt and non-vector interrupt, it might be more necessary than plic/aia.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes I would suggest a couple of enhancements arising from this. Firstly, the CLIC introduces interrupt levels as well as priorities (levels determine what interrupts can preempt others at the same privilege level, whereas priorities determine the order in which simultaneous interrupts are taken). So I propose to add APIs for setting interrupt levels and level threshold.
Also, I propose to say that the BSP should use vectored interrupts where possible, and we can introduce an additional API to allow users to register a "raw" handler that will be plugged directly into the vector table for a particular mcause (bypassing the base trap handler supplied by the BSP). This allows users to create their own fast, customized handler for a particular mcause (but the disadvantage is that the user's handler in that case would need to do all context save-and restore for itself - whereas a handler registered with csi_register_m_isr or csi_register_u_isr doesn't need to deal with that because the base handler does it).


/*
* Interrupt enable bits in the mie CSR
*/
typedef enum {
CSI_SW_INTERRUPTS_ENABLE = 8, /* Software interrupts enable bit index */
CSI_TIMER_INTERRUPTS_ENABLE = 128, /* Timer interrupts enable bit index */
CSI_EXT_INTERRUPTS_ENABLE = 2048, /* External interrupts enable bit index */
} csi_interrupt_enables_t;


#endif /* CSI_DEFS_H */
Loading