xref: /linux/arch/loongarch/include/asm/kvm_eiointc.h (revision 2e8b9df82631e714cc2b7bf302772c8259673180)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2024 Loongson Technology Corporation Limited
4  */
5 
6 #ifndef __ASM_KVM_EIOINTC_H
7 #define __ASM_KVM_EIOINTC_H
8 
9 #include <kvm/iodev.h>
10 
11 #define EIOINTC_IRQS			256
12 #define EIOINTC_ROUTE_MAX_VCPUS		256
13 #define EIOINTC_IRQS_U8_NUMS		(EIOINTC_IRQS / 8)
14 #define EIOINTC_IRQS_U16_NUMS		(EIOINTC_IRQS_U8_NUMS / 2)
15 #define EIOINTC_IRQS_U32_NUMS		(EIOINTC_IRQS_U8_NUMS / 4)
16 #define EIOINTC_IRQS_U64_NUMS		(EIOINTC_IRQS_U8_NUMS / 8)
17 /* map to ipnum per 32 irqs */
18 #define EIOINTC_IRQS_NODETYPE_COUNT	16
19 
20 #define EIOINTC_BASE			0x1400
21 #define EIOINTC_SIZE			0x900
22 
23 #define EIOINTC_VIRT_BASE		(0x40000000)
24 #define EIOINTC_VIRT_SIZE		(0x1000)
25 
26 #define LOONGSON_IP_NUM			8
27 
28 struct loongarch_eiointc {
29 	spinlock_t lock;
30 	struct kvm *kvm;
31 	struct kvm_io_device device;
32 	struct kvm_io_device device_vext;
33 	uint32_t num_cpu;
34 	uint32_t features;
35 	uint32_t status;
36 
37 	/* hardware state */
38 	union nodetype {
39 		u64 reg_u64[EIOINTC_IRQS_NODETYPE_COUNT / 4];
40 		u32 reg_u32[EIOINTC_IRQS_NODETYPE_COUNT / 2];
41 		u16 reg_u16[EIOINTC_IRQS_NODETYPE_COUNT];
42 		u8 reg_u8[EIOINTC_IRQS_NODETYPE_COUNT * 2];
43 	} nodetype;
44 
45 	/* one bit shows the state of one irq */
46 	union bounce {
47 		u64 reg_u64[EIOINTC_IRQS_U64_NUMS];
48 		u32 reg_u32[EIOINTC_IRQS_U32_NUMS];
49 		u16 reg_u16[EIOINTC_IRQS_U16_NUMS];
50 		u8 reg_u8[EIOINTC_IRQS_U8_NUMS];
51 	} bounce;
52 
53 	union isr {
54 		u64 reg_u64[EIOINTC_IRQS_U64_NUMS];
55 		u32 reg_u32[EIOINTC_IRQS_U32_NUMS];
56 		u16 reg_u16[EIOINTC_IRQS_U16_NUMS];
57 		u8 reg_u8[EIOINTC_IRQS_U8_NUMS];
58 	} isr;
59 	union coreisr {
60 		u64 reg_u64[EIOINTC_ROUTE_MAX_VCPUS][EIOINTC_IRQS_U64_NUMS];
61 		u32 reg_u32[EIOINTC_ROUTE_MAX_VCPUS][EIOINTC_IRQS_U32_NUMS];
62 		u16 reg_u16[EIOINTC_ROUTE_MAX_VCPUS][EIOINTC_IRQS_U16_NUMS];
63 		u8 reg_u8[EIOINTC_ROUTE_MAX_VCPUS][EIOINTC_IRQS_U8_NUMS];
64 	} coreisr;
65 	union enable {
66 		u64 reg_u64[EIOINTC_IRQS_U64_NUMS];
67 		u32 reg_u32[EIOINTC_IRQS_U32_NUMS];
68 		u16 reg_u16[EIOINTC_IRQS_U16_NUMS];
69 		u8 reg_u8[EIOINTC_IRQS_U8_NUMS];
70 	} enable;
71 
72 	/* use one byte to config ipmap for 32 irqs at once */
73 	union ipmap {
74 		u64 reg_u64;
75 		u32 reg_u32[EIOINTC_IRQS_U32_NUMS / 4];
76 		u16 reg_u16[EIOINTC_IRQS_U16_NUMS / 4];
77 		u8 reg_u8[EIOINTC_IRQS_U8_NUMS / 4];
78 	} ipmap;
79 	/* use one byte to config coremap for one irq */
80 	union coremap {
81 		u64 reg_u64[EIOINTC_IRQS / 8];
82 		u32 reg_u32[EIOINTC_IRQS / 4];
83 		u16 reg_u16[EIOINTC_IRQS / 2];
84 		u8 reg_u8[EIOINTC_IRQS];
85 	} coremap;
86 
87 	DECLARE_BITMAP(sw_coreisr[EIOINTC_ROUTE_MAX_VCPUS][LOONGSON_IP_NUM], EIOINTC_IRQS);
88 	uint8_t  sw_coremap[EIOINTC_IRQS];
89 };
90 
91 int kvm_loongarch_register_eiointc_device(void);
92 
93 #endif /* __ASM_KVM_EIOINTC_H */
94