mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-11-09 20:45:41 +08:00
[DRIVER/PIC] Add ARM GICv2/v3 V2M, ITS support.
Fix some code style and init for V2M, ITS. V2M is the PCI MSI/MSI-X for GICv2. ITS is the PCI MSI/MSI-X for GICv3/v4. Signed-off-by: GuEe-GUI <2991707448@qq.com>
This commit is contained in:
1 parent
94e49755af
commit
3d503e931b
8 files changed
+2157
-54
No files matched your search
@@ -1,6 +1,7 @@
|
||||
menuconfig RT_USING_PIC
|
||||
bool "Using Programmable Interrupt Controller (PIC)"
|
||||
select RT_USING_BITMAP
|
||||
select RT_USING_ADT
|
||||
select RT_USING_ADT_BITMAP
|
||||
depends on RT_USING_DM
|
||||
default n
|
||||
|
||||
@@ -22,12 +23,31 @@ config RT_PIC_ARM_GIC
|
||||
select RT_USING_OFW
|
||||
default n
|
||||
|
||||
config RT_PIC_ARM_GIC_V2M
|
||||
bool "ARM GIC V2M" if RT_PIC_ARM_GIC && RT_PCI_MSI
|
||||
depends on RT_USING_OFW
|
||||
default n
|
||||
|
||||
config RT_PIC_ARM_GIC_V3
|
||||
bool "ARM GICv3"
|
||||
depends on RT_USING_PIC
|
||||
select RT_USING_OFW
|
||||
default n
|
||||
|
||||
config RT_PIC_ARM_GIC_V3_ITS
|
||||
bool "ARM GICv3 ITS (Interrupt Translation Service)" if RT_PIC_ARM_GIC_V3 && RT_PCI_MSI
|
||||
depends on RT_USING_OFW
|
||||
select RT_USING_ADT_REF
|
||||
default n
|
||||
|
||||
config RT_PIC_ARM_GIC_V3_ITS_IRQ_MAX
|
||||
int "IRQ maximum used"
|
||||
depends on RT_PIC_ARM_GIC_V3_ITS
|
||||
default 127 if ARCH_CPU_64BIT
|
||||
default 63
|
||||
help
|
||||
Recommended to be based on the bit length (full bits) of maximum usage.
|
||||
|
||||
config RT_PIC_ARM_GIC_MAX_NR
|
||||
int
|
||||
depends on RT_USING_PIC
|
||||
|
||||
@@ -16,9 +16,15 @@ if GetDepend(['RT_PIC_ARM_GIC']) or GetDepend(['RT_PIC_ARM_GIC_V3']):
|
||||
if GetDepend(['RT_PIC_ARM_GIC']):
|
||||
src += ['pic-gicv2.c']
|
||||
|
||||
if GetDepend(['RT_PIC_ARM_GIC_V2M']):
|
||||
src += ['pic-gicv2m.c']
|
||||
|
||||
if GetDepend(['RT_PIC_ARM_GIC_V3']):
|
||||
src += ['pic-gicv3.c']
|
||||
|
||||
if GetDepend(['RT_PIC_ARM_GIC_V3_ITS']):
|
||||
src += ['pic-gicv3-its.c']
|
||||
|
||||
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
||||
@@ -8,10 +8,14 @@
|
||||
* 2023-01-30 GuEe-GUI first version
|
||||
*/
|
||||
|
||||
#ifndef __IRQ_GIC_COMMON_H__
|
||||
#define __IRQ_GIC_COMMON_H__
|
||||
#ifndef __PIC_GIC_COMMON_H__
|
||||
#define __PIC_GIC_COMMON_H__
|
||||
|
||||
#include <rtdef.h>
|
||||
|
||||
#ifdef RT_PCI_MSI
|
||||
#include <drivers/pci_msi.h>
|
||||
#endif
|
||||
#include <drivers/ofw.h>
|
||||
|
||||
#define GIC_SGI_NR 16
|
||||
@@ -52,4 +56,4 @@ rt_err_t gicv2m_ofw_probe(struct rt_ofw_node *ic_np, const struct rt_ofw_node_id
|
||||
rt_err_t gicv3_its_ofw_probe(struct rt_ofw_node *ic_np, const struct rt_ofw_node_id *id);
|
||||
#endif
|
||||
|
||||
#endif /* __IRQ_GIC_COMMON_H__ */
|
||||
#endif /* __PIC_GIC_COMMON_H__ */
|
||||
@@ -128,6 +128,8 @@ static void gicv2_cpu_init(struct gicv2 *gic)
|
||||
|
||||
#ifdef ARCH_SUPPORT_HYP
|
||||
_gicv2_eoi_mode_ns = RT_TRUE;
|
||||
#else
|
||||
_gicv2_eoi_mode_ns = !!rt_ofw_bootargs_select("pic.gicv2_eoimode", 0);
|
||||
#endif
|
||||
|
||||
if (_gicv2_eoi_mode_ns)
|
||||
|
||||
Executable
+378
File diff suppressed because it is too large.
Load diff
Executable
+1584
File diff suppressed because it is too large.
Load diff
@@ -266,20 +266,25 @@ static void gicv3_dist_init(void)
|
||||
HWREG64(base + GICD_IROUTERnE + i * 8) = affinity;
|
||||
}
|
||||
|
||||
if (GICD_TYPER_NUM_LPIS(_gic.gicd_typer))
|
||||
if (GICD_TYPER_NUM_LPIS(_gic.gicd_typer) > 1)
|
||||
{
|
||||
/* Max LPI = 8192 + Math.pow(2, num_LPIs + 1) - 1 */
|
||||
rt_size_t num_lpis = (1 << (GICD_TYPER_NUM_LPIS(_gic.gicd_typer) + 1)) + 1;
|
||||
rt_size_t num_lpis = 1UL << (GICD_TYPER_NUM_LPIS(_gic.gicd_typer) + 1);
|
||||
|
||||
_gic.lpi_nr = rt_min_t(int, num_lpis, 1 << GICD_TYPER_ID_BITS(_gic.gicd_typer));
|
||||
_gic.lpi_nr = rt_min_t(int, num_lpis, 1UL << GICD_TYPER_ID_BITS(_gic.gicd_typer));
|
||||
}
|
||||
else
|
||||
{
|
||||
_gic.lpi_nr = 1 << GICD_TYPER_ID_BITS(_gic.gicd_typer);
|
||||
_gic.lpi_nr = 1UL << GICD_TYPER_ID_BITS(_gic.gicd_typer);
|
||||
}
|
||||
|
||||
/* SPI + eSPI + LPIs */
|
||||
_gic.irq_nr = _gic.line_nr - 32 + _gic.espi_nr + _gic.lpi_nr;
|
||||
_gic.irq_nr = _gic.line_nr - 32 + _gic.espi_nr;
|
||||
#ifdef RT_PIC_ARM_GIC_V3_ITS
|
||||
/* ITS will allocate the same number of lpi PIRQs */
|
||||
_gic.lpi_nr = rt_min_t(rt_size_t, RT_PIC_ARM_GIC_V3_ITS_IRQ_MAX, _gic.lpi_nr);
|
||||
_gic.irq_nr += _gic.lpi_nr;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void gicv3_redist_enable(rt_bool_t enable)
|
||||
@@ -389,6 +394,8 @@ static void gicv3_cpu_init(void)
|
||||
int cpu_id = rt_hw_cpu_id();
|
||||
#ifdef ARCH_SUPPORT_HYP
|
||||
_gicv3_eoi_mode_ns = RT_TRUE;
|
||||
#else
|
||||
_gicv3_eoi_mode_ns = !!rt_ofw_bootargs_select("pic.gicv3_eoimode", 0);
|
||||
#endif
|
||||
|
||||
base = gicv3_percpu_redist_sgi_base();
|
||||
@@ -700,6 +707,7 @@ static int gicv3_irq_map(struct rt_pic *pic, int hwirq, rt_uint32_t mode)
|
||||
if (pirq && hwirq >= GIC_SGI_NR)
|
||||
{
|
||||
pirq->mode = mode;
|
||||
pirq->priority = GICD_INT_DEF_PRI;
|
||||
|
||||
switch (gicv3_hwirq_type(hwirq))
|
||||
{
|
||||
@@ -708,7 +716,6 @@ static int gicv3_irq_map(struct rt_pic *pic, int hwirq, rt_uint32_t mode)
|
||||
break;
|
||||
case SPI_TYPE:
|
||||
case ESPI_TYPE:
|
||||
pirq->priority = GICD_INT_DEF_PRI;
|
||||
RT_IRQ_AFFINITY_SET(pirq->affinity, _init_cpu_id);
|
||||
default:
|
||||
break;
|
||||
@@ -823,7 +830,18 @@ static rt_bool_t gicv3_handler(void *data)
|
||||
}
|
||||
else
|
||||
{
|
||||
pirq = rt_pic_find_irq(&gic->parent, hwirq - GIC_SGI_NR);
|
||||
int irq_index;
|
||||
|
||||
if (hwirq < 8192)
|
||||
{
|
||||
irq_index = hwirq - GIC_SGI_NR;
|
||||
}
|
||||
else
|
||||
{
|
||||
irq_index = gic->irq_nr - gic->lpi_nr + hwirq - 8192;
|
||||
}
|
||||
|
||||
pirq = rt_pic_find_irq(&gic->parent, irq_index);
|
||||
}
|
||||
|
||||
gicv3_irq_ack(pirq);
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user