-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
[RFC] riscv: drivers: Implement APLIC and IMSIC drivers #7236
base: master
Are you sure you want to change the base?
Conversation
By the way, I used some of the code related to APLIC and IMSIC from Linux and OpenSBI. Should I inform the original authors or take any specific actions? |
If you copy code, you must do so under the license provided by the copyright holder and preserve the copyright. However, we don't accept GPL licenses (copyleft) in OP-TEE. The copyright holder may agree to change the license, but it can get tricky if there are many copyright holders. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comments to core/drivers/aplic_direct.c may apply to other source files.
Please fix all indention issue. Can use scripts/checkpatch.sh
to fund them.
Thank you for your insights. I need to consider removing the part of code copied from Linux and rewrite the relevant parts. Additionally, since OpenSBI https://github.com/riscv-software-src/opensbi under the BSD-2-Clause license, I can use their code in my PR by preserve the copyright, right? |
Correct. |
dabed47
to
d0e5ed0
Compare
@maroueneboubakri Do you have interest to review this PR? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some coding style and other minor comments.
Hi @HuangBorong , An year ago I implemented a simple UART RX interrupt handler to test secure interrupt. static void read_console(void)
{
struct serial_chip *cons = &console_data.chip;
if (!cons->ops->getchar || !cons->ops->have_rx_data)
return;
while (cons->ops->have_rx_data(cons)) {
int ch __maybe_unused = cons->ops->getchar(cons);
DMSG("got 0x%x", ch);
}
}
static enum itr_return console_itr_cb(struct itr_handler *h __maybe_unused)
{
read_console();
return ITRR_HANDLED;
}
static struct itr_handler console_itr = {
.it = UART1_IRQ,
.flags = ITRF_TRIGGER_LEVEL,
.handler = console_itr_cb,
};
DECLARE_KEEP_PAGER(console_itr);
static TEE_Result init_console_itr(void)
{
TEE_Result res = TEE_ERROR_GENERIC;
console_itr.chip = interrupt_get_main_chip();
res = interrupt_add_configure_handler(&console_itr, IRQ_TYPE_LEVEL_HIGH,
1);
if (res)
return res;
interrupt_enable(console_itr.chip, console_itr.it);
return TEE_SUCCESS;
}
driver_init(init_console_itr); |
@HuangBorong , About the Supervisor top interrupt CSR (stopi), yes we definitely need it. #if defined(CFG_RISCV_APLIC_MSI) || defined(CFG_RISCV_IMSIC)
void thread_native_interrupt_handler(struct thread_ctx_regs *regs,
unsigned long cause)
{
unsigned long topi;
while ((topi = csr_read(CSR_XTOPI))) {
topi = topi >> TOPI_IID_SHIFT;
switch (topi) {
case IRQ_XTIMER:
clear_csr(CSR_XIE, CSR_XIE_TIE);
break;
case IRQ_XSOFT:
thread_unhandled_trap(regs, cause);
break;
case IRQ_XEXT:
thread_irq_handler();
break;
default:
thread_unhandled_trap(regs, cause);
}
}
}
#endif |
@gagachang Thank you for your review! I have fixed the issues you mentioned above in commit 5d901b7. |
You're welcome, did you test secure interrupt ? |
Hi @gagachang, So far, I’ve tested secure interrupts in APLIC direct mode. You can find my code in my repository https://github.com/HuangBorong/riscv-optee-dev-env/tree/test-aplic-direct under the branch To test the secure interrupt, I’ve done the following:
However, I’ve encountered an issue: While OP-TEE successfully receives interrupts from the timer, it fails to receive interrupts from UART RX. However, the console is able to capture the characters I enter. I’m unsure whether this is due to a misconfiguration or related to other underlying problems. |
Sorry I forgot to give you some configurations. You need to enable |
Thanks! I can receive UART interrupt now. |
Great! It seems the APLIC direct mode works well. |
Implement the IMSIC driver introduced by the AIA specification, enabling initialization based on the device tree. Add CSRs for indirect access to the IMSIC and for reading interrupt identity. Signed-off-by: Huang Borong <[email protected]>
…C) driver Implement the APLIC driver introduced by the AIA specification, supporting direct delivery mode and MSI delivery mode. Initialization can be done through the device tree. Signed-off-by: Huang Borong <[email protected]>
Signed-off-by: Huang Borong <[email protected]>
…mation 1. Fix indentation issues 2. Fix variable initialization problems 3. Reorder header files alphabetically 4. Remov redundant comments and add new ones for clarity 5. Add open-source license information as part of secondary development based on OpenSBI 6. Refactor portions of the code to improve readability
- Change condition to check for NULL address - Prevent potential NULL pointer dereference
- Fix indentation issues - Add error handling for device tree parsing - Refactor IMSIC CSR access functions - Update platform configuration for IMSIC - Fix some code style issues
- Bug Fixes: Resolved identified issues to ensure proper functionality - Code Refactoring: Removed redundant and unnecessary code segments - Code Style Enhancements: Improved coding style
@HuangBorong You can hide the resolved reviews so that the reviewers can know which reviews were resolved. |
56853ba
to
a3b6f79
Compare
- Update interrupt controller configuration macros - Fix coding sytle issues
a3b6f79
to
ae8b182
Compare
I haven't tested the IMSIC/MSI yet.
Could APLIC MSI delivery mode test the IMSIC? The APLIC can convert the wire interrupt into an MSI write and send it to IMSIC. |
Oh! You are right. We can configure secure timer or UART to use APLIC MSI delivery mode. |
@@ -28,6 +28,9 @@ $(call force,CFG_BOOT_SYNC_CPU,n) | |||
|
|||
# Interrupt controller | |||
CFG_RISCV_PLIC ?= y | |||
CFG_RISCV_APLIC ?= n | |||
CFG_RISCV_APLIC_MSI ?= n | |||
CFG_RISCV_IMSIC ?= n |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CFG_RISCV_PLIC
is incompatible with the other three configurations.
I think they must not be enabled simultaneously.
Recommend to add check on this case:
ifeq ($(CFG_RISCV_PLIC)-$(call cfg-one-enabled,CFG_RISCV_APLIC CFG_RISCV_APLIC_MSI CFG_RISCV_IMSIC),y-y)
$(error PLIC is incompatible with AIA)
endif
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The check can be added into core/arch/riscv/riscv.mk
.
if (id == IMSIC_IPI_ID) | ||
DMSG("Interprocessor interrupt"); | ||
|
||
if (id > 1 && id <= imsic->num_ids) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer using macro instead of hardcode.
if (IMSIC_IPI_ID < id && id <= imsic->num_ids)
imsic->hart_index_bits = fdt32_to_cpu(*val); | ||
else | ||
imsic->hart_index_bits = 32 - | ||
__builtin_clz(CFG_TEE_CORE_NB_CORE - 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest to put calculation in one line:
imsic->hart_index_bits =
32 - __builtin_clz(CFG_TEE_CORE_NB_CORE - 1);
Implement the APLIC and IMSIC drivers which introduced by the "RISC-V Advanced Interrupt Architecture" specification: https://github.com/riscv/riscv-aia
The drivers support two modes:
Some systems without IMSIC only have APLIC, which replaces the original PLIC as the Advanced PLIC. The role of APLIC is to serve as interrupt controllers.
In these systems, both APLIC and IMSIC are present. The harts receive external interrupts only in the form of MSIs. Therefore, the role of APLIC is to convert wired interrupts into MSIs for harts, while the interrupt controllers in these systems are IMSICs.
There are some limitations in the drivers: