tools/testing/selftests/kvm/lib/arm64/gic_v3.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/kvm/lib/arm64/gic_v3.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/kvm/lib/arm64/gic_v3.c
Extension
.c
Size
11325 bytes
Lines
450
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct gicv3_data {
	unsigned int nr_cpus;
	unsigned int nr_spis;
};

#define sgi_base_from_redist(redist_base)	(redist_base + SZ_64K)
#define DIST_BIT				(1U << 31)

enum gicv3_intid_range {
	SGI_RANGE,
	PPI_RANGE,
	SPI_RANGE,
	INVALID_RANGE,
};

static struct gicv3_data gicv3_data;

static void gicv3_gicd_wait_for_rwp(void)
{
	unsigned int count = 100000; /* 1s */

	while (readl(GICD_BASE_GVA + GICD_CTLR) & GICD_CTLR_RWP) {
		GUEST_ASSERT(count--);
		udelay(10);
	}
}

static inline volatile void *gicr_base_cpu(u32 cpu)
{
	/* Align all the redistributors sequentially */
	return GICR_BASE_GVA + cpu * SZ_64K * 2;
}

static void gicv3_gicr_wait_for_rwp(u32 cpu)
{
	unsigned int count = 100000; /* 1s */

	while (readl(gicr_base_cpu(cpu) + GICR_CTLR) & GICR_CTLR_RWP) {
		GUEST_ASSERT(count--);
		udelay(10);
	}
}

static void gicv3_wait_for_rwp(u32 cpu_or_dist)
{
	if (cpu_or_dist & DIST_BIT)
		gicv3_gicd_wait_for_rwp();
	else
		gicv3_gicr_wait_for_rwp(cpu_or_dist);
}

static enum gicv3_intid_range get_intid_range(unsigned int intid)
{
	switch (intid) {
	case 0 ... 15:
		return SGI_RANGE;
	case 16 ... 31:
		return PPI_RANGE;
	case 32 ... 1019:
		return SPI_RANGE;
	}

	/* We should not be reaching here */
	GUEST_ASSERT(0);

	return INVALID_RANGE;
}

static u64 gicv3_read_iar(void)
{
	u64 irqstat = read_sysreg_s(SYS_ICC_IAR1_EL1);

	dsb(sy);
	return irqstat;
}

static void gicv3_write_eoir(u32 irq)
{
	write_sysreg_s(irq, SYS_ICC_EOIR1_EL1);
	isb();
}

static void gicv3_write_dir(u32 irq)
{
	write_sysreg_s(irq, SYS_ICC_DIR_EL1);
	isb();
}

static void gicv3_set_priority_mask(u64 mask)
{

Annotation

Implementation Notes