arch/riscv/kvm/aia_imsic.c

Source file repositories/reference/linux-study-clean/arch/riscv/kvm/aia_imsic.c

File Facts

System
Linux kernel
Corpus path
arch/riscv/kvm/aia_imsic.c
Extension
.c
Size
31974 bytes
Lines
1176
Domain
Architecture Layer
Bucket
arch/riscv
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

struct imsic_mrif_eix {
	unsigned long eip[BITS_PER_TYPE(u64) / BITS_PER_LONG];
	unsigned long eie[BITS_PER_TYPE(u64) / BITS_PER_LONG];
};

struct imsic_mrif {
	struct imsic_mrif_eix eix[IMSIC_MAX_EIX];
	unsigned long eithreshold;
	unsigned long eidelivery;
};

struct imsic {
	struct kvm_io_device iodev;

	u32 nr_msis;
	u32 nr_eix;
	u32 nr_hw_eix;

	/*
	 * At any point in time, the register state is in
	 * one of the following places:
	 *
	 * 1) Hardware: IMSIC VS-file (vsfile_cpu >= 0)
	 * 2) Software: IMSIC SW-file (vsfile_cpu < 0)
	 */

	/* IMSIC VS-file */
	rwlock_t vsfile_lock;
	int vsfile_cpu;
	int vsfile_hgei;
	void __iomem *vsfile_va;
	phys_addr_t vsfile_pa;

	/* IMSIC SW-file */
	struct imsic_mrif *swfile;
	phys_addr_t swfile_pa;
	raw_spinlock_t swfile_extirq_lock;
};

#define imsic_vs_csr_read(__c)			\
({						\
	unsigned long __r;			\
	csr_write(CSR_VSISELECT, __c);		\
	__r = csr_read(CSR_VSIREG);		\
	__r;					\
})

#define imsic_read_switchcase(__ireg)			\
	case __ireg:					\
		return imsic_vs_csr_read(__ireg);
#define imsic_read_switchcase_2(__ireg)			\
	imsic_read_switchcase(__ireg + 0)		\
	imsic_read_switchcase(__ireg + 1)
#define imsic_read_switchcase_4(__ireg)			\
	imsic_read_switchcase_2(__ireg + 0)		\
	imsic_read_switchcase_2(__ireg + 2)
#define imsic_read_switchcase_8(__ireg)			\
	imsic_read_switchcase_4(__ireg + 0)		\
	imsic_read_switchcase_4(__ireg + 4)
#define imsic_read_switchcase_16(__ireg)		\
	imsic_read_switchcase_8(__ireg + 0)		\
	imsic_read_switchcase_8(__ireg + 8)
#define imsic_read_switchcase_32(__ireg)		\
	imsic_read_switchcase_16(__ireg + 0)		\
	imsic_read_switchcase_16(__ireg + 16)
#define imsic_read_switchcase_64(__ireg)		\
	imsic_read_switchcase_32(__ireg + 0)		\
	imsic_read_switchcase_32(__ireg + 32)

static unsigned long imsic_eix_read(int ireg)
{
	switch (ireg) {
	imsic_read_switchcase_64(IMSIC_EIP0)
	imsic_read_switchcase_64(IMSIC_EIE0)
	}

	return 0;
}

#define imsic_vs_csr_swap(__c, __v)		\
({						\
	unsigned long __r;			\
	csr_write(CSR_VSISELECT, __c);		\
	__r = csr_swap(CSR_VSIREG, __v);	\
	__r;					\
})

#define imsic_swap_switchcase(__ireg, __v)		\
	case __ireg:					\
		return imsic_vs_csr_swap(__ireg, __v);

Annotation

Implementation Notes