Commit 2f412eb7 authored by Bibo Mao's avatar Bibo Mao Committed by Huacai Chen
Browse files

LoongArch: KVM: Set version information at initial stage



Register PCH_PIC_INT_ID constains version and supported irq number
information, and it is a read only register. The detailed value can
be set at initial stage, rather than read callback.

Signed-off-by: default avatarBibo Mao <maobibo@loongson.cn>
Signed-off-by: default avatarHuacai Chen <chenhuacai@loongson.cn>
parent 3da2b0d4
Loading
Loading
Loading
Loading
+14 −1
Original line number Diff line number Diff line
@@ -34,13 +34,26 @@
#define PCH_PIC_INT_ISR_END		0x3af
#define PCH_PIC_POLARITY_START		0x3e0
#define PCH_PIC_POLARITY_END		0x3e7
#define PCH_PIC_INT_ID_VAL		0x7000000UL
#define PCH_PIC_INT_ID_VAL		0x7UL
#define PCH_PIC_INT_ID_VER		0x1UL

union pch_pic_id {
	struct {
		uint8_t reserved_0[3];
		uint8_t id;
		uint8_t version;
		uint8_t reserved_1;
		uint8_t irq_num;
		uint8_t reserved_2;
	} desc;
	uint64_t data;
};

struct loongarch_pch_pic {
	spinlock_t lock;
	struct kvm *kvm;
	struct kvm_io_device device;
	union pch_pic_id id;
	uint64_t mask; /* 1:disable irq, 0:enable irq */
	uint64_t htmsi_en; /* 1:msi */
	uint64_t edge; /* 1:edge triggered, 0:level triggered */
+18 −9
Original line number Diff line number Diff line
@@ -120,20 +120,13 @@ static int loongarch_pch_pic_read(struct loongarch_pch_pic *s, gpa_t addr, int l
{
	int offset, index, ret = 0;
	u32 data = 0;
	u64 int_id = 0;

	offset = addr - s->pch_pic_base;

	spin_lock(&s->lock);
	switch (offset) {
	case PCH_PIC_INT_ID_START ... PCH_PIC_INT_ID_END:
		/* int id version */
		int_id |= (u64)PCH_PIC_INT_ID_VER << 32;
		/* irq number */
		int_id |= (u64)31 << (32 + 16);
		/* int id value */
		int_id |= PCH_PIC_INT_ID_VAL;
		*(u64 *)val = int_id;
		*(u64 *)val = s->id.data;
		break;
	case PCH_PIC_MASK_START ... PCH_PIC_MASK_END:
		offset -= PCH_PIC_MASK_START;
@@ -484,7 +477,7 @@ static int kvm_setup_default_irq_routing(struct kvm *kvm)

static int kvm_pch_pic_create(struct kvm_device *dev, u32 type)
{
	int ret;
	int i, ret, irq_num;
	struct kvm *kvm = dev->kvm;
	struct loongarch_pch_pic *s;

@@ -500,6 +493,22 @@ static int kvm_pch_pic_create(struct kvm_device *dev, u32 type)
	if (!s)
		return -ENOMEM;

	/*
	 * Interrupt controller identification register 1
	 *   Bit 24-31 Interrupt Controller ID
	 * Interrupt controller identification register 2
	 *   Bit  0-7  Interrupt Controller version number
	 *   Bit 16-23 The number of interrupt sources supported
	 */
	irq_num = 32;
	s->mask = -1UL;
	s->id.desc.id = PCH_PIC_INT_ID_VAL;
	s->id.desc.version = PCH_PIC_INT_ID_VER;
	s->id.desc.irq_num = irq_num - 1;
	for (i = 0; i < irq_num; i++) {
		s->route_entry[i] = 1;
		s->htmsi_vector[i] = i;
	}
	spin_lock_init(&s->lock);
	s->kvm = kvm;
	kvm->arch.pch_pic = s;