[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:
parent
94e49755af
commit
3d503e931b
|
@ -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)
|
||||
|
|
|
@ -0,0 +1,378 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2022-11-07 GuEe-GUI first version
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
#define DBG_TAG "pic.gicv2m"
|
||||
#define DBG_LVL DBG_INFO
|
||||
#include <rtdbg.h>
|
||||
|
||||
#include <mmu.h>
|
||||
#include <cpuport.h>
|
||||
#include "pic-gic-common.h"
|
||||
|
||||
/*
|
||||
* MSI_TYPER:
|
||||
* [31:26] Reserved
|
||||
* [25:16] lowest SPI assigned to MSI
|
||||
* [15:10] Reserved
|
||||
* [9:0] Numer of SPIs assigned to MSI
|
||||
*/
|
||||
#define V2M_MSI_TYPER 0x008
|
||||
#define V2M_MSI_TYPER_BASE_SHIFT 16
|
||||
#define V2M_MSI_TYPER_BASE_MASK 0x3ff
|
||||
#define V2M_MSI_TYPER_NUM_MASK 0x3ff
|
||||
#define V2M_MSI_SETSPI_NS 0x040
|
||||
#define V2M_MIN_SPI 32
|
||||
#define V2M_MAX_SPI 1019
|
||||
#define V2M_MSI_IIDR 0xfcc
|
||||
|
||||
#define V2M_MSI_TYPER_BASE_SPI(x) (((x) >> V2M_MSI_TYPER_BASE_SHIFT) & V2M_MSI_TYPER_BASE_MASK)
|
||||
#define V2M_MSI_TYPER_NUM_SPI(x) ((x) & V2M_MSI_TYPER_NUM_MASK)
|
||||
|
||||
/* APM X-Gene with GICv2m MSI_IIDR register value */
|
||||
#define XGENE_GICV2M_MSI_IIDR 0x06000170
|
||||
/* Broadcom NS2 GICv2m MSI_IIDR register value */
|
||||
#define BCM_NS2_GICV2M_MSI_IIDR 0x0000013f
|
||||
|
||||
/* List of flags for specific v2m implementation */
|
||||
#define GICV2M_NEEDS_SPI_OFFSET 0x00000001
|
||||
#define GICV2M_GRAVITON_ADDRESS_ONLY 0x00000002
|
||||
|
||||
struct gicv2m
|
||||
{
|
||||
struct rt_pic parent;
|
||||
|
||||
void *base;
|
||||
void *base_phy;
|
||||
rt_uint32_t spi_start; /* The SPI number that MSIs start */
|
||||
rt_uint32_t spis_nr; /* The number of SPIs for MSIs */
|
||||
rt_uint32_t spi_offset; /* Offset to be subtracted from SPI number */
|
||||
|
||||
rt_bitmap_t *vectors; /* MSI vector bitmap */
|
||||
rt_uint32_t flags; /* Flags for v2m's specific implementation */
|
||||
|
||||
void *gic;
|
||||
struct rt_spinlock lock;
|
||||
};
|
||||
|
||||
#define raw_to_gicv2m(raw) rt_container_of(raw, struct gicv2m, parent)
|
||||
|
||||
static rt_ubase_t gicv2m_get_msi_addr(struct gicv2m *v2m, int hwirq)
|
||||
{
|
||||
rt_ubase_t addr;
|
||||
|
||||
if (v2m->flags & GICV2M_GRAVITON_ADDRESS_ONLY)
|
||||
{
|
||||
addr = (rt_ubase_t)v2m->base_phy | ((hwirq - 32) << 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
addr = (rt_ubase_t)v2m->base_phy + V2M_MSI_SETSPI_NS;
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
static rt_bool_t is_msi_spi_valid(rt_uint32_t base, rt_uint32_t num)
|
||||
{
|
||||
if (base < V2M_MIN_SPI)
|
||||
{
|
||||
LOG_E("Invalid MSI base SPI (base: %u)", base);
|
||||
|
||||
return RT_FALSE;
|
||||
}
|
||||
else if ((num == 0) || (base + num > V2M_MAX_SPI))
|
||||
{
|
||||
LOG_E("Number of SPIs (%u) exceed maximum (%u)", num, V2M_MAX_SPI - V2M_MIN_SPI + 1);
|
||||
|
||||
return RT_FALSE;
|
||||
}
|
||||
|
||||
return RT_TRUE;
|
||||
}
|
||||
|
||||
static void gicv2m_irq_mask(struct rt_pic_irq *pirq)
|
||||
{
|
||||
rt_pci_msi_mask_irq(pirq);
|
||||
rt_pic_irq_parent_mask(pirq);
|
||||
}
|
||||
|
||||
static void gicv2m_irq_unmask(struct rt_pic_irq *pirq)
|
||||
{
|
||||
rt_pci_msi_unmask_irq(pirq);
|
||||
rt_pic_irq_parent_unmask(pirq);
|
||||
}
|
||||
|
||||
static void gicv2m_compose_msi_msg(struct rt_pic_irq *pirq, struct rt_pci_msi_msg *msg)
|
||||
{
|
||||
rt_ubase_t addr;
|
||||
struct gicv2m *v2m = raw_to_gicv2m(pirq->pic);
|
||||
|
||||
addr = gicv2m_get_msi_addr(v2m, pirq->hwirq);
|
||||
|
||||
msg->address_hi = rt_upper_32_bits(addr);
|
||||
msg->address_lo = rt_lower_32_bits(addr);
|
||||
|
||||
if (v2m->flags & GICV2M_GRAVITON_ADDRESS_ONLY)
|
||||
{
|
||||
msg->data = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
msg->data = pirq->hwirq;
|
||||
}
|
||||
|
||||
if (v2m->flags & GICV2M_NEEDS_SPI_OFFSET)
|
||||
{
|
||||
msg->data -= v2m->spi_offset;
|
||||
}
|
||||
}
|
||||
|
||||
static int gicv2m_irq_alloc_msi(struct rt_pic *pic, struct rt_pci_msi_desc *msi_desc)
|
||||
{
|
||||
rt_ubase_t level;
|
||||
int irq, parent_irq, hwirq, hwirq_index;
|
||||
struct rt_pic_irq *pirq;
|
||||
struct gicv2m *v2m = raw_to_gicv2m(pic);
|
||||
struct rt_pic *ppic = v2m->gic;
|
||||
|
||||
level = rt_spin_lock_irqsave(&v2m->lock);
|
||||
hwirq_index = rt_bitmap_next_clear_bit(v2m->vectors, 0, v2m->spis_nr);
|
||||
|
||||
if (hwirq_index >= v2m->spis_nr)
|
||||
{
|
||||
irq = -RT_EEMPTY;
|
||||
goto _out_lock;
|
||||
}
|
||||
|
||||
hwirq = v2m->spi_start + v2m->spi_offset + hwirq_index;
|
||||
|
||||
parent_irq = ppic->ops->irq_map(ppic, hwirq, RT_IRQ_MODE_EDGE_RISING);
|
||||
if (parent_irq < 0)
|
||||
{
|
||||
irq = parent_irq;
|
||||
goto _out_lock;
|
||||
}
|
||||
|
||||
irq = rt_pic_config_irq(pic, hwirq_index, hwirq);
|
||||
if (irq < 0)
|
||||
{
|
||||
goto _out_lock;
|
||||
}
|
||||
pirq = rt_pic_find_irq(pic, hwirq_index);
|
||||
|
||||
pirq->mode = RT_IRQ_MODE_EDGE_RISING;
|
||||
rt_pic_cascade(pirq, parent_irq);
|
||||
|
||||
rt_bitmap_set_bit(v2m->vectors, hwirq_index);
|
||||
|
||||
_out_lock:
|
||||
rt_spin_unlock_irqrestore(&v2m->lock, level);
|
||||
|
||||
return irq;
|
||||
}
|
||||
|
||||
static void gicv2m_irq_free_msi(struct rt_pic *pic, int irq)
|
||||
{
|
||||
rt_ubase_t level;
|
||||
struct rt_pic_irq *pirq;
|
||||
struct gicv2m *v2m = raw_to_gicv2m(pic);
|
||||
|
||||
pirq = rt_pic_find_pirq(pic, irq);
|
||||
|
||||
if (!pirq)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
rt_pic_uncascade(pirq);
|
||||
|
||||
level = rt_spin_lock_irqsave(&v2m->lock);
|
||||
rt_bitmap_clear_bit(v2m->vectors, pirq->hwirq - (v2m->spi_start + v2m->spi_offset));
|
||||
rt_spin_unlock_irqrestore(&v2m->lock, level);
|
||||
}
|
||||
|
||||
static rt_err_t gicv2m_irq_set_state(struct rt_pic *pic, int hwirq, int type, rt_bool_t state)
|
||||
{
|
||||
struct gicv2m *v2m = raw_to_gicv2m(pic);
|
||||
struct rt_pic *ppic = v2m->gic;
|
||||
|
||||
return ppic->ops->irq_set_state(ppic, hwirq, type, state);
|
||||
}
|
||||
|
||||
static rt_err_t gicv2m_irq_get_state(struct rt_pic *pic, int hwirq, int type, rt_bool_t *out_state)
|
||||
{
|
||||
struct gicv2m *v2m = raw_to_gicv2m(pic);
|
||||
struct rt_pic *ppic = v2m->gic;
|
||||
|
||||
return ppic->ops->irq_get_state(ppic, hwirq, type, out_state);
|
||||
}
|
||||
|
||||
const static struct rt_pic_ops gicv2m_ops =
|
||||
{
|
||||
.name = "GICv2m",
|
||||
.irq_ack = rt_pic_irq_parent_ack,
|
||||
.irq_mask = gicv2m_irq_mask,
|
||||
.irq_unmask = gicv2m_irq_unmask,
|
||||
.irq_eoi = rt_pic_irq_parent_eoi,
|
||||
.irq_set_priority = rt_pic_irq_parent_set_priority,
|
||||
.irq_set_affinity = rt_pic_irq_parent_set_affinity,
|
||||
.irq_compose_msi_msg = gicv2m_compose_msi_msg,
|
||||
.irq_alloc_msi = gicv2m_irq_alloc_msi,
|
||||
.irq_free_msi = gicv2m_irq_free_msi,
|
||||
.irq_set_state = gicv2m_irq_set_state,
|
||||
.irq_get_state = gicv2m_irq_get_state,
|
||||
.flags = RT_PIC_F_IRQ_ROUTING,
|
||||
};
|
||||
|
||||
static const struct rt_ofw_node_id gicv2m_ofw_match[] =
|
||||
{
|
||||
{ .compatible = "arm,gic-v2m-frame" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
rt_err_t gicv2m_ofw_probe(struct rt_ofw_node *np, const struct rt_ofw_node_id *id)
|
||||
{
|
||||
rt_err_t err = RT_EOK;
|
||||
struct rt_ofw_node *v2m_np;
|
||||
|
||||
rt_ofw_foreach_available_child_node(np, v2m_np)
|
||||
{
|
||||
struct gicv2m *v2m;
|
||||
rt_size_t bitmap_size;
|
||||
rt_uint32_t spi_start = 0, spis_nr = 0;
|
||||
|
||||
if (!rt_ofw_node_match(v2m_np, gicv2m_ofw_match))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!rt_ofw_prop_read_bool(v2m_np, "msi-controller"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(v2m = rt_malloc(sizeof(*v2m))))
|
||||
{
|
||||
rt_ofw_node_put(v2m_np);
|
||||
|
||||
err = -RT_ENOMEM;
|
||||
break;
|
||||
}
|
||||
|
||||
v2m->base = rt_ofw_iomap(v2m_np, 0);
|
||||
|
||||
if (!v2m->base)
|
||||
{
|
||||
LOG_E("%s: IO map failed", rt_ofw_node_full_name(v2m_np));
|
||||
continue;
|
||||
}
|
||||
|
||||
v2m->base_phy = rt_kmem_v2p(v2m->base);
|
||||
v2m->flags = 0;
|
||||
|
||||
if (!rt_ofw_prop_read_u32(v2m_np, "arm,msi-base-spi", &spi_start) &&
|
||||
!rt_ofw_prop_read_u32(v2m_np, "arm,msi-num-spis", &spis_nr))
|
||||
{
|
||||
LOG_I("DT overriding V2M MSI_TYPER (base:%u, num:%u)", spi_start, spis_nr);
|
||||
}
|
||||
|
||||
if (spi_start && spis_nr)
|
||||
{
|
||||
v2m->spi_start = spi_start;
|
||||
v2m->spis_nr = spis_nr;
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_uint32_t typer;
|
||||
|
||||
/* Graviton should always have explicit spi_start/spis_nr */
|
||||
if (v2m->flags & GICV2M_GRAVITON_ADDRESS_ONLY)
|
||||
{
|
||||
goto _fail;
|
||||
}
|
||||
typer = HWREG32(v2m->base + V2M_MSI_TYPER);
|
||||
|
||||
v2m->spi_start = V2M_MSI_TYPER_BASE_SPI(typer);
|
||||
v2m->spis_nr = V2M_MSI_TYPER_NUM_SPI(typer);
|
||||
}
|
||||
|
||||
if (!is_msi_spi_valid(v2m->spi_start, v2m->spis_nr))
|
||||
{
|
||||
goto _fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* APM X-Gene GICv2m implementation has an erratum where
|
||||
* the MSI data needs to be the offset from the spi_start
|
||||
* in order to trigger the correct MSI interrupt. This is
|
||||
* different from the standard GICv2m implementation where
|
||||
* the MSI data is the absolute value within the range from
|
||||
* spi_start to (spi_start + num_spis).
|
||||
*
|
||||
* Broadcom NS2 GICv2m implementation has an erratum where the MSI data
|
||||
* is 'spi_number - 32'
|
||||
*
|
||||
* Reading that register fails on the Graviton implementation
|
||||
*/
|
||||
if (!(v2m->flags & GICV2M_GRAVITON_ADDRESS_ONLY))
|
||||
{
|
||||
switch (HWREG32(v2m->base + V2M_MSI_IIDR))
|
||||
{
|
||||
case XGENE_GICV2M_MSI_IIDR:
|
||||
v2m->flags |= GICV2M_NEEDS_SPI_OFFSET;
|
||||
v2m->spi_offset = v2m->spi_start;
|
||||
break;
|
||||
|
||||
case BCM_NS2_GICV2M_MSI_IIDR:
|
||||
v2m->flags |= GICV2M_NEEDS_SPI_OFFSET;
|
||||
v2m->spi_offset = 32;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bitmap_size = RT_BITMAP_LEN(v2m->spis_nr) * sizeof(bitmap_t);
|
||||
|
||||
if (!(v2m->vectors = rt_calloc(1, bitmap_size)))
|
||||
{
|
||||
err = -RT_ENOMEM;
|
||||
goto _fail;
|
||||
}
|
||||
|
||||
rt_spin_lock_init(&v2m->lock);
|
||||
|
||||
v2m->parent.priv_data = v2m;
|
||||
v2m->parent.ops = &gicv2m_ops;
|
||||
v2m->gic = rt_ofw_data(np);
|
||||
|
||||
rt_pic_linear_irq(&v2m->parent, v2m->spis_nr);
|
||||
rt_pic_user_extends(&v2m->parent);
|
||||
|
||||
rt_ofw_data(v2m_np) = &v2m->parent;
|
||||
rt_ofw_node_set_flag(v2m_np, RT_OFW_F_READLY);
|
||||
|
||||
continue;
|
||||
|
||||
_fail:
|
||||
rt_iounmap(v2m->base);
|
||||
rt_free(v2m);
|
||||
|
||||
if (err)
|
||||
{
|
||||
rt_ofw_node_put(v2m_np);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
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);
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
* 2023-02-01 GuEe-GUI move macros to header
|
||||
*/
|
||||
|
||||
#ifndef __IRQ_GICV3_H__
|
||||
#define __IRQ_GICV3_H__
|
||||
#ifndef __PIC_GICV3_H__
|
||||
#define __PIC_GICV3_H__
|
||||
|
||||
#include <rtdef.h>
|
||||
|
||||
|
@ -101,6 +101,8 @@
|
|||
#define GICR_CTLR_IR (1UL << 2)
|
||||
#define GICR_CTLR_RWP (1UL << 3)
|
||||
|
||||
#define GICR_TYPER_CPU_NO(r) (((r) >> 8) & 0xffff)
|
||||
|
||||
#define GICR_RD_BASE_SIZE (64 * SIZE_KB)
|
||||
#define GICR_SGI_OFFSET (64 * SIZE_KB)
|
||||
#define GICR_SGI_BASE_SIZE GICR_SGI_OFFSET
|
||||
|
@ -152,15 +154,47 @@
|
|||
#define GITS_CTLR 0x0000
|
||||
#define GITS_IIDR 0x0004
|
||||
#define GITS_TYPER 0x0008
|
||||
#define GITS_MPAMIDR 0x0010
|
||||
#define GITS_PARTIDR 0x0014
|
||||
#define GITS_MPIDR 0x0018
|
||||
#define GITS_STATUSR 0x0040
|
||||
#define GITS_UMSIR 0x0048
|
||||
#define GITS_CBASER 0x0048
|
||||
#define GITS_CBASER 0x0080
|
||||
#define GITS_CWRITER 0x0088
|
||||
#define GITS_CREADR 0x0090
|
||||
#define GITS_BASER 0x0100 /* 0x0100~0x0138 */
|
||||
#define GITS_BASER 0x0100
|
||||
#define GITS_IDREGS_BASE 0xffd0
|
||||
#define GITS_PIDR0 0xffe0
|
||||
#define GITS_PIDR1 0xffe4
|
||||
#define GITS_PIDR2 GICR_PIDR2
|
||||
#define GITS_PIDR4 0xffd0
|
||||
#define GITS_CIDR0 0xfff0
|
||||
#define GITS_CIDR1 0xfff4
|
||||
#define GITS_CIDR2 0xfff8
|
||||
#define GITS_CIDR3 0xfffc
|
||||
|
||||
#define GITS_TRANSLATER 0x10040
|
||||
|
||||
#define GITS_SGIR 0x20020
|
||||
|
||||
#define GITS_SGIR_VPEID RT_GENMASK_ULL(47, 32)
|
||||
#define GITS_SGIR_VINTID RT_GENMASK_ULL(3, 0)
|
||||
|
||||
#define GITS_CTLR_ENABLE (1U << 0)
|
||||
#define GITS_CTLR_ImDe (1U << 1)
|
||||
#define GITS_CTLR_ITS_NUMBER_SHIFT 4
|
||||
#define GITS_CTLR_ITS_NUMBER (0xFU << GITS_CTLR_ITS_NUMBER_SHIFT)
|
||||
#define GITS_CTLR_QUIESCENT (1U << 31)
|
||||
|
||||
#define GITS_TYPER_PLPIS (1UL << 0)
|
||||
#define GITS_TYPER_VLPIS (1UL << 1)
|
||||
#define GITS_TYPER_ITT_ENTRY_SIZE_SHIFT 4
|
||||
#define GITS_TYPER_ITT_ENTRY_SIZE RT_GENMASK_ULL(7, 4)
|
||||
#define GITS_TYPER_IDBITS_SHIFT 8
|
||||
#define GITS_TYPER_DEVBITS_SHIFT 13
|
||||
#define GITS_TYPER_DEVBITS RT_GENMASK_ULL(17, 13)
|
||||
#define GITS_TYPER_PTA (1UL << 19)
|
||||
#define GITS_TYPER_HCC_SHIFT 24
|
||||
#define GITS_TYPER_HCC(r) (((r) >> GITS_TYPER_HCC_SHIFT) & 0xff)
|
||||
#define GITS_TYPER_VMOVP (1ULL << 37)
|
||||
#define GITS_TYPER_VMAPP (1ULL << 40)
|
||||
#define GITS_TYPER_SVPET RT_GENMASK_ULL(42, 41)
|
||||
|
||||
/*
|
||||
* ITS commands
|
||||
|
@ -183,35 +217,79 @@
|
|||
#define GITS_LPI_CFG_ENABLED (1 << 0)
|
||||
|
||||
/* ITS Command Queue Descriptor */
|
||||
#define GITS_BASER_SHAREABILITY_SHIFT 10
|
||||
#define GITS_BASER_INNER_CACHEABILITY_SHIFT 59
|
||||
#define GITS_BASER_OUTER_CACHEABILITY_SHIFT 53
|
||||
#define GITS_CBASER_VALID (1UL << 63)
|
||||
#define GITS_CBASER_SHAREABILITY_SHIFT (10)
|
||||
#define GITS_CBASER_INNER_CACHEABILITY_SHIFT (59)
|
||||
#define GITS_CBASER_OUTER_CACHEABILITY_SHIFT (53)
|
||||
#define GITS_CBASER_SHAREABILITY_SHIFT 10
|
||||
#define GITS_CBASER_INNER_CACHEABILITY_SHIFT 59
|
||||
#define GITS_CBASER_OUTER_CACHEABILITY_SHIFT 53
|
||||
#define GICR_PBASER_SHAREABILITY_SHIFT 10
|
||||
#define GICR_PBASER_INNER_CACHEABILITY_SHIFT 7
|
||||
#define GICR_PBASER_OUTER_CACHEABILITY_SHIFT 56
|
||||
|
||||
#define GITS_TRANSLATION_TABLE_DESCRIPTORS_NR 8
|
||||
#define GITS_BASER_NR_REGS 8
|
||||
#define GITS_BASERn(idx) (GITS_BASER + sizeof(rt_uint64_t) * idx)
|
||||
|
||||
#define GITS_BASER_VALID (1ULL << 63)
|
||||
#define GITS_BASER_INDIRECT (1ULL << 62)
|
||||
#define GITS_BASER_TYPE_SHIFT 56
|
||||
#define GITS_BASER_TYPE(r) (((r) >> GITS_BASER_TYPE_SHIFT) & 7)
|
||||
#define GITS_BASER_ENTRY_SIZE_SHIFT 48
|
||||
#define GITS_BASER_ENTRY_SIZE(r) ((((r) >> GITS_BASER_ENTRY_SIZE_SHIFT) & 0x1f) + 1)
|
||||
#define GITS_BASER_PAGE_SIZE_SHIFT 8
|
||||
#define GITS_BASER_PAGE_SIZE_4K (0ULL << GITS_BASER_PAGE_SIZE_SHIFT)
|
||||
#define GITS_BASER_PAGE_SIZE_16K (1ULL << GITS_BASER_PAGE_SIZE_SHIFT)
|
||||
#define GITS_BASER_PAGE_SIZE_64K (2ULL << GITS_BASER_PAGE_SIZE_SHIFT)
|
||||
#define GITS_BASER_PAGE_SIZE_MASK (3ULL << GITS_BASER_PAGE_SIZE_SHIFT)
|
||||
#define GITS_BASER_PAGES_SHIFT 0
|
||||
|
||||
#define GITS_LVL1_ENTRY_SIZE 8UL
|
||||
|
||||
#define GITS_BASER_TYPE_NONE 0
|
||||
#define GITS_BASER_TYPE_DEVICE 1
|
||||
#define GITS_BASER_TYPE_VPE 2
|
||||
#define GITS_BASER_TYPE_RESERVED3 3
|
||||
#define GITS_BASER_TYPE_COLLECTION 4
|
||||
#define GITS_BASER_TYPE_RESERVED5 5
|
||||
#define GITS_BASER_TYPE_RESERVED6 6
|
||||
#define GITS_BASER_TYPE_RESERVED7 7
|
||||
|
||||
#define GITS_BASER_CACHEABILITY(reg, inner_outer, type) \
|
||||
(GITS_CBASER_CACHE_##type << reg##_##inner_outer##_CACHEABILITY_SHIFT)
|
||||
(GIC_BASER_CACHE_##type << reg##_##inner_outer##_CACHEABILITY_SHIFT)
|
||||
#define GITS_BASER_SHAREABILITY(reg, type) \
|
||||
(GITS_CBASER_##type << reg##_SHAREABILITY_SHIFT)
|
||||
(GIC_BASER_##type << reg##_SHAREABILITY_SHIFT)
|
||||
|
||||
#define GITS_CBASER_CACHE_DnGnRnE 0x0UL /* Device-nGnRnE. */
|
||||
#define GITS_CBASER_CACHE_NIN 0x1UL /* Normal Inner Non-cacheable. */
|
||||
#define GITS_CBASER_CACHE_NIRAWT 0x2UL /* Normal Inner Cacheable Read-allocate, Write-through. */
|
||||
#define GITS_CBASER_CACHE_NIRAWB 0x3UL /* Normal Inner Cacheable Read-allocate, Write-back. */
|
||||
#define GITS_CBASER_CACHE_NIWAWT 0x4UL /* Normal Inner Cacheable Write-allocate, Write-through. */
|
||||
#define GITS_CBASER_CACHE_NIWAWB 0x5UL /* Normal Inner Cacheable Write-allocate, Write-back. */
|
||||
#define GITS_CBASER_CACHE_NIRAWAWT 0x6UL /* Normal Inner Cacheable Read-allocate, Write-allocate, Write-through. */
|
||||
#define GITS_CBASER_CACHE_NIRAWAWB 0x7UL /* Normal Inner Cacheable Read-allocate, Write-allocate, Write-back. */
|
||||
#define GITS_CBASER_CACHE_MASK 0x7UL
|
||||
#define GITS_CBASER_SHARE_NS 0x0UL /* Non-shareable. */
|
||||
#define GITS_CBASER_SHARE_IS 0x1UL /* Inner Shareable. */
|
||||
#define GITS_CBASER_SHARE_OS 0x2UL /* Outer Shareable. */
|
||||
#define GITS_CBASER_SHARE_RES 0x3UL /* Reserved. Treated as 0b00 */
|
||||
#define GITS_CBASER_SHARE_MASK 0x3UL
|
||||
#define GIC_BASER_CACHE_DnGnRnE 0x0UL /* Device-nGnRnE. */
|
||||
#define GIC_BASER_CACHE_NIN 0x1UL /* Normal Inner Non-cacheable. */
|
||||
#define GIC_BASER_CACHE_NIRAWT 0x2UL /* Normal Inner Cacheable Read-allocate, Write-through. */
|
||||
#define GIC_BASER_CACHE_NIRAWB 0x3UL /* Normal Inner Cacheable Read-allocate, Write-back. */
|
||||
#define GIC_BASER_CACHE_NIWAWT 0x4UL /* Normal Inner Cacheable Write-allocate, Write-through. */
|
||||
#define GIC_BASER_CACHE_NIWAWB 0x5UL /* Normal Inner Cacheable Write-allocate, Write-back. */
|
||||
#define GIC_BASER_CACHE_NIRAWAWT 0x6UL /* Normal Inner Cacheable Read-allocate, Write-allocate, Write-through. */
|
||||
#define GIC_BASER_CACHE_NIRAWAWB 0x7UL /* Normal Inner Cacheable Read-allocate, Write-allocate, Write-back. */
|
||||
#define GIC_BASER_CACHE_MASK 0x7UL
|
||||
#define GIC_BASER_SHARE_NS 0x0UL /* Non-shareable. */
|
||||
#define GIC_BASER_SHARE_IS 0x1UL /* Inner Shareable. */
|
||||
#define GIC_BASER_SHARE_OS 0x2UL /* Outer Shareable. */
|
||||
#define GIC_BASER_SHARE_RES 0x3UL /* Reserved. Treated as 0b00 */
|
||||
#define GIC_BASER_SHARE_MASK 0x3UL
|
||||
|
||||
#define GITS_BASER_InnerShareable GITS_BASER_SHAREABILITY(GITS_BASER, SHARE_IS)
|
||||
#define GITS_BASER_SHARE_MASK_ALL GITS_BASER_SHAREABILITY(GITS_BASER, SHARE_MASK)
|
||||
#define GITS_BASER_INNER_MASK_ALL GITS_BASER_CACHEABILITY(GITS_BASER, INNER, MASK)
|
||||
#define GITS_BASER_nCnB GITS_BASER_CACHEABILITY(GITS_BASER, INNER, DnGnRnE)
|
||||
#define GITS_BASER_nC GITS_BASER_CACHEABILITY(GITS_BASER, INNER, NIN)
|
||||
#define GITS_BASER_RaWt GITS_BASER_CACHEABILITY(GITS_BASER, INNER, NIRAWT)
|
||||
#define GITS_BASER_RaWb GITS_BASER_CACHEABILITY(GITS_BASER, INNER, NIRAWB)
|
||||
#define GITS_BASER_WaWt GITS_BASER_CACHEABILITY(GITS_BASER, INNER, NIWAWT)
|
||||
#define GITS_BASER_WaWb GITS_BASER_CACHEABILITY(GITS_BASER, INNER, NIWAWB)
|
||||
#define GITS_BASER_RaWaWt GITS_BASER_CACHEABILITY(GITS_BASER, INNER, NIRAWAWT)
|
||||
#define GITS_BASER_RaWaWb GITS_BASER_CACHEABILITY(GITS_BASER, INNER, NIRAWAWB)
|
||||
|
||||
#define GITS_CBASER_InnerShareable GITS_BASER_SHAREABILITY(GITS_CBASER, SHARE_IS)
|
||||
#define GITS_CBASER_SHARE_MASK_ALL GITS_BASER_SHAREABILITY(GITS_CBASER, SHARE_MASK)
|
||||
#define GITS_CBASER_INNER_MASK_ALL GITS_BASER_CACHEABILITY(GITS_CBASER, INNER, MASK)
|
||||
#define GITS_CBASER_nCnB GITS_BASER_CACHEABILITY(GITS_CBASER, INNER, DnGnRnE)
|
||||
#define GITS_CBASER_nC GITS_BASER_CACHEABILITY(GITS_CBASER, INNER, NIN)
|
||||
#define GITS_CBASER_RaWt GITS_BASER_CACHEABILITY(GITS_CBASER, INNER, NIRAWT)
|
||||
|
@ -221,6 +299,18 @@
|
|||
#define GITS_CBASER_RaWaWt GITS_BASER_CACHEABILITY(GITS_CBASER, INNER, NIRAWAWT)
|
||||
#define GITS_CBASER_RaWaWb GITS_BASER_CACHEABILITY(GITS_CBASER, INNER, NIRAWAWB)
|
||||
|
||||
#define GICR_PBASER_InnerShareable GITS_BASER_SHAREABILITY(GICR_PBASER, SHARE_IS)
|
||||
#define GICR_PBASER_SHARE_MASK_ALL GITS_BASER_SHAREABILITY(GICR_PBASER, SHARE_MASK)
|
||||
#define GICR_PBASER_INNER_MASK_ALL GITS_BASER_CACHEABILITY(GICR_PBASER, INNER, MASK)
|
||||
#define GICR_PBASER_nCnB GITS_BASER_CACHEABILITY(GICR_PBASER, INNER, DnGnRnE)
|
||||
#define GICR_PBASER_nC GITS_BASER_CACHEABILITY(GICR_PBASER, INNER, NIN)
|
||||
#define GICR_PBASER_RaWt GITS_BASER_CACHEABILITY(GICR_PBASER, INNER, NIRAWT)
|
||||
#define GICR_PBASER_RaWb GITS_BASER_CACHEABILITY(GICR_PBASER, INNER, NIRAWB)
|
||||
#define GICR_PBASER_WaWt GITS_BASER_CACHEABILITY(GICR_PBASER, INNER, NIWAWT)
|
||||
#define GICR_PBASER_WaWb GITS_BASER_CACHEABILITY(GICR_PBASER, INNER, NIWAWB)
|
||||
#define GICR_PBASER_RaWaWt GITS_BASER_CACHEABILITY(GICR_PBASER, INNER, NIRAWAWT)
|
||||
#define GICR_PBASER_RaWaWb GITS_BASER_CACHEABILITY(GICR_PBASER, INNER, NIRAWAWB)
|
||||
|
||||
#define GIC_EPPI_BASE_INTID 1056
|
||||
#define GIC_ESPI_BASE_INTID 4096
|
||||
|
||||
|
@ -283,6 +373,7 @@ struct gicv3
|
|||
rt_size_t dist_size;
|
||||
|
||||
void *redist_percpu_base[RT_CPUS_NR];
|
||||
rt_uint64_t redist_percpu_flags[RT_CPUS_NR];
|
||||
rt_size_t percpu_ppi_nr[RT_CPUS_NR];
|
||||
|
||||
struct
|
||||
|
@ -296,4 +387,4 @@ struct gicv3
|
|||
rt_size_t redist_regions_nr;
|
||||
};
|
||||
|
||||
#endif /* __IRQ_GICV3_H__ */
|
||||
#endif /* __PIC_GICV3_H__ */
|
||||
|
|
Loading…
Reference in New Issue