drivers: intc: RP2350: Add initial support for Hazard3

The RP2350 uses the Xh3irq interrupt controller, which supports nested
and prioritised interrupts. This adds initial support, configuring the
controller in 'direct' (non-vectored) mode.

Signed-off-by: Andrew Featherstone <andrew.featherstone@gmail.com>
This commit is contained in:
Andrew Featherstone
2025-01-07 22:03:08 +00:00
committed by Chris Friedt
parent d88193cba9
commit 80a54a89cd
9 changed files with 157 additions and 0 deletions

View File

@@ -14,6 +14,8 @@ zephyr_library_sources_ifdef(CONFIG_GIC_V2 intc_gic.c)
zephyr_library_sources_ifdef(CONFIG_GIC_V3 intc_gicv3.c)
zephyr_library_sources_ifdef(CONFIG_GIC_V3_ITS intc_gicv3_its.c)
zephyr_library_sources_ifdef(CONFIG_GPIO_INTC_STM32WB0 intc_gpio_stm32wb0.c)
zephyr_library_sources_ifdef(CONFIG_HAZARD3_INTC intc_hazard3.c)
zephyr_library_sources_ifdef(CONFIG_HAZARD3_INTC intc_hazard3.S)
zephyr_library_sources_ifdef(CONFIG_INTEL_VTD_ICTL intc_intel_vtd.c)
zephyr_library_sources_ifdef(CONFIG_IOAPIC intc_ioapic.c)
zephyr_library_sources_ifdef(CONFIG_ITE_IT51XXX_INTC intc_ite_it51xxx.c)

View File

@@ -30,6 +30,15 @@ config VEXRISCV_LITEX_IRQ
help
IRQ implementation for LiteX VexRiscv
config HAZARD3_INTC
bool "Hazard3 interrupt controller"
default y
select PICOSDK_USE_CLAIM
select RISCV_SOC_HAS_CUSTOM_IRQ_HANDLING
depends on DT_HAS_HAZARD3_HAZARD3_INTC_ENABLED
help
IRQ implementation for Hazard3 Interrupt Controller found on the RP2350 series SoCs
config LEON_IRQMP
bool "GRLIB IRQMP interrupt controller"
default y

View File

@@ -0,0 +1,64 @@
/*
* Copyright (C) 2025 Andrew Featherstone
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/toolchain.h>
#include "hardware/platform_defs.h"
#include "hardware/regs/rvcsr.h"
/* imports */
#ifdef CONFIG_TRACING
GTEXT(sys_trace_isr_enter)
GTEXT(sys_trace_isr_exit)
#endif
/* exports */
GTEXT(__soc_handle_all_irqs)
/*
* This function services and clears all pending interrupts.
*/
SECTION_FUNC(exception.other, __soc_handle_all_irqs)
/* Get the highest-priority external interrupt. */
csrr a0, RVCSR_MEINEXT_OFFSET
bltz a0, irq_done
addi sp, sp, -16
sw ra, 0(sp)
irq_loop:
#ifdef CONFIG_TRACING_ISR
call sys_trace_isr_enter
#endif
/*
* Call corresponding registered function in _sw_isr_table.
* Value from MEINEXT is index left shifted by 2, so shift
* by one to get offset into 2-word wide table.
*/
la t0, _sw_isr_table
slli a0, a0, (1)
add t0, t0, a0
/* Load argument in a0 register */
lw a0, 0(t0)
/* Load ISR function address in register t1 */
lw t1, 4(t0)
/* Call ISR function */
jalr ra, t1, 0
#ifdef CONFIG_TRACING_ISR
call sys_trace_isr_exit
#endif
/* Get the next highest interrupt, and process that, or continue to done. */
csrr a0, RVCSR_MEINEXT_OFFSET
bgez a0, irq_loop
lw ra, 0(sp)
addi sp, sp, 16
irq_done:
ret

View File

@@ -0,0 +1,53 @@
/*
* Copyright (c) 2025 Andrew Featherstone
*
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT hazard3_hazard3_intc
#include <zephyr/kernel.h>
#include <zephyr/arch/cpu.h>
#include <zephyr/irq.h>
#include <zephyr/device.h>
#include <zephyr/types.h>
#include <zephyr/arch/riscv/csr.h>
#include <zephyr/arch/riscv/irq.h>
#include <pico/runtime_init.h>
#include <hardware/irq.h>
#define CSR_WINDOW_SIZE 16
void arch_irq_enable(unsigned int irq)
{
irq_set_enabled(irq, true);
}
void arch_irq_disable(unsigned int irq)
{
irq_set_enabled(irq, false);
}
int arch_irq_is_enabled(unsigned int irq)
{
return pico_irq_is_enabled(irq);
}
static int hazard3_irq_init(const struct device *dev)
{
/* Clear all IRQ force array bits. */
for (int i = 0; (i * CSR_WINDOW_SIZE) < CONFIG_NUM_IRQS; i++) {
hazard3_irqarray_clear(RVCSR_MEIFA_OFFSET, i, -1);
}
/* Global external IRQ enable. */
csr_write(mie, RVCSR_MIE_MEIE_BITS);
csr_set(mstatus, MSTATUS_IEN);
return 0;
}
DEVICE_DT_INST_DEFINE(0, hazard3_irq_init, NULL, NULL, NULL,
PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY, NULL);

View File

@@ -0,0 +1,13 @@
description: Hazard3 interrupt controller
compatible: "hazard3,hazard3-intc"
include: [interrupt-controller.yaml, base.yaml]
properties:
"#interrupt-cells":
const: 2
interrupt-cells:
- irq
- priority

View File

@@ -286,6 +286,7 @@ hamamatsu Hamamatsu Photonics K.K.
hannstar HannStar Display Corporation
haoyu Haoyu Microelectronic Co. Ltd.
hardkernel Hardkernel Co., Ltd
hazard3 Hazard3 by Luke Wren
heltec Chengdu Heltec Automation Technology Co., Ltd.
hideep HiDeep Inc.
himax Himax Technologies, Inc.

View File

@@ -155,6 +155,14 @@ if(CONFIG_HAS_RPI_PICO)
zephyr_include_directories_ifdef(CONFIG_PICOSDK_USE_CLAIM
${common_dir}/hardware_claim/include)
zephyr_include_directories_ifdef(CONFIG_RISCV
${common_dir}/pico_sync/include
${common_dir}/pico_time/include
${rp2_common_dir}/hardware_hazard3/include
${rp2_common_dir}/hardware_riscv/include)
zephyr_library_sources_ifdef(CONFIG_RISCV
${rp2_common_dir}/hardware_irq/irq.c)
zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_RP2350
${rp2_common_dir}/pico_runtime_init/runtime_init.c)
zephyr_include_directories_ifdef(CONFIG_SOC_SERIES_RP2350

View File

@@ -45,4 +45,9 @@
/* Definition required for the flash driver */
#define __STRING(x) #x
/* Enable the HAL to work with minimal modification when using a minimal libc. */
#ifndef __CONCAT
#define __CONCAT CONCAT
#endif
#endif

View File

@@ -18,7 +18,9 @@
void soc_reset_hook(void)
{
#if SOC_RP2350A_M33
runtime_init_per_core_enable_coprocessors();
#endif
}
#endif /* CONFIG_SOC_RESET_HOOK */