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

LoongArch: KVM: Add different length support in loongarch_pch_pic_read()



With function loongarch_pch_pic_read(), currently it is hardcoded length
for different registers, and the length comes from exising linux pch_pic
driver code. But in theory, all length 1/2/4/8 should be supported for
all the registers, here add different length support about register read
emulation in function loongarch_pch_pic_read().

Signed-off-by: default avatarBibo Mao <maobibo@loongson.cn>
Signed-off-by: default avatarHuacai Chen <chenhuacai@loongson.cn>
parent eb626c77
Loading
Loading
Loading
Loading
+19 −23
Original line number Diff line number Diff line
@@ -118,55 +118,45 @@ static u32 pch_pic_write_reg(u64 *s, int high, u32 v)

static int loongarch_pch_pic_read(struct loongarch_pch_pic *s, gpa_t addr, int len, void *val)
{
	int offset, index, ret = 0;
	u32 data = 0;
	int ret = 0, offset;
	u64 data = 0;
	void *ptemp;

	offset = addr - s->pch_pic_base;
	offset -= offset & 7;

	spin_lock(&s->lock);
	switch (offset) {
	case PCH_PIC_INT_ID_START ... PCH_PIC_INT_ID_END:
		*(u64 *)val = s->id.data;
		data = s->id.data;
		break;
	case PCH_PIC_MASK_START ... PCH_PIC_MASK_END:
		offset -= PCH_PIC_MASK_START;
		index = offset >> 2;
		/* read mask reg */
		data = pch_pic_read_reg(&s->mask, index);
		*(u32 *)val = data;
		data = s->mask;
		break;
	case PCH_PIC_HTMSI_EN_START ... PCH_PIC_HTMSI_EN_END:
		offset -= PCH_PIC_HTMSI_EN_START;
		index = offset >> 2;
		/* read htmsi enable reg */
		data = pch_pic_read_reg(&s->htmsi_en, index);
		*(u32 *)val = data;
		data = s->htmsi_en;
		break;
	case PCH_PIC_EDGE_START ... PCH_PIC_EDGE_END:
		offset -= PCH_PIC_EDGE_START;
		index = offset >> 2;
		/* read edge enable reg */
		data = pch_pic_read_reg(&s->edge, index);
		*(u32 *)val = data;
		data = s->edge;
		break;
	case PCH_PIC_AUTO_CTRL0_START ... PCH_PIC_AUTO_CTRL0_END:
	case PCH_PIC_AUTO_CTRL1_START ... PCH_PIC_AUTO_CTRL1_END:
		/* we only use default mode: fixed interrupt distribution mode */
		*(u32 *)val = 0;
		break;
	case PCH_PIC_ROUTE_ENTRY_START ... PCH_PIC_ROUTE_ENTRY_END:
		/* only route to int0: eiointc */
		*(u8 *)val = 1;
		ptemp = s->route_entry + (offset - PCH_PIC_ROUTE_ENTRY_START);
		data = *(u64 *)ptemp;
		break;
	case PCH_PIC_HTMSI_VEC_START ... PCH_PIC_HTMSI_VEC_END:
		offset -= PCH_PIC_HTMSI_VEC_START;
		/* read htmsi vector */
		data = s->htmsi_vector[offset];
		*(u8 *)val = data;
		ptemp = s->htmsi_vector + (offset - PCH_PIC_HTMSI_VEC_START);
		data = *(u64 *)ptemp;
		break;
	case PCH_PIC_POLARITY_START ... PCH_PIC_POLARITY_END:
		/* we only use defalut value 0: high level triggered */
		*(u32 *)val = 0;
		data = s->polarity;
		break;
	case PCH_PIC_INT_IRR_START:
		data = s->irr;
@@ -179,6 +169,12 @@ static int loongarch_pch_pic_read(struct loongarch_pch_pic *s, gpa_t addr, int l
	}
	spin_unlock(&s->lock);

	if (ret == 0) {
		offset = (addr - s->pch_pic_base) & 7;
		data = data >> (offset * 8);
		memcpy(val, &data, len);
	}

	return ret;
}