12e8b9df8SXianglai Li /* SPDX-License-Identifier: GPL-2.0 */ 22e8b9df8SXianglai Li /* 32e8b9df8SXianglai Li * Copyright (C) 2024 Loongson Technology Corporation Limited 42e8b9df8SXianglai Li */ 52e8b9df8SXianglai Li 62e8b9df8SXianglai Li #ifndef __ASM_KVM_EIOINTC_H 72e8b9df8SXianglai Li #define __ASM_KVM_EIOINTC_H 82e8b9df8SXianglai Li 92e8b9df8SXianglai Li #include <kvm/iodev.h> 102e8b9df8SXianglai Li 112e8b9df8SXianglai Li #define EIOINTC_IRQS 256 122e8b9df8SXianglai Li #define EIOINTC_ROUTE_MAX_VCPUS 256 132e8b9df8SXianglai Li #define EIOINTC_IRQS_U8_NUMS (EIOINTC_IRQS / 8) 142e8b9df8SXianglai Li #define EIOINTC_IRQS_U16_NUMS (EIOINTC_IRQS_U8_NUMS / 2) 152e8b9df8SXianglai Li #define EIOINTC_IRQS_U32_NUMS (EIOINTC_IRQS_U8_NUMS / 4) 162e8b9df8SXianglai Li #define EIOINTC_IRQS_U64_NUMS (EIOINTC_IRQS_U8_NUMS / 8) 172e8b9df8SXianglai Li /* map to ipnum per 32 irqs */ 182e8b9df8SXianglai Li #define EIOINTC_IRQS_NODETYPE_COUNT 16 192e8b9df8SXianglai Li 202e8b9df8SXianglai Li #define EIOINTC_BASE 0x1400 212e8b9df8SXianglai Li #define EIOINTC_SIZE 0x900 222e8b9df8SXianglai Li 23*3956a52bSXianglai Li #define EIOINTC_NODETYPE_START 0xa0 24*3956a52bSXianglai Li #define EIOINTC_NODETYPE_END 0xbf 25*3956a52bSXianglai Li #define EIOINTC_IPMAP_START 0xc0 26*3956a52bSXianglai Li #define EIOINTC_IPMAP_END 0xc7 27*3956a52bSXianglai Li #define EIOINTC_ENABLE_START 0x200 28*3956a52bSXianglai Li #define EIOINTC_ENABLE_END 0x21f 29*3956a52bSXianglai Li #define EIOINTC_BOUNCE_START 0x280 30*3956a52bSXianglai Li #define EIOINTC_BOUNCE_END 0x29f 31*3956a52bSXianglai Li #define EIOINTC_ISR_START 0x300 32*3956a52bSXianglai Li #define EIOINTC_ISR_END 0x31f 33*3956a52bSXianglai Li #define EIOINTC_COREISR_START 0x400 34*3956a52bSXianglai Li #define EIOINTC_COREISR_END 0x41f 35*3956a52bSXianglai Li #define EIOINTC_COREMAP_START 0x800 36*3956a52bSXianglai Li #define EIOINTC_COREMAP_END 0x8ff 37*3956a52bSXianglai Li 382e8b9df8SXianglai Li #define EIOINTC_VIRT_BASE (0x40000000) 392e8b9df8SXianglai Li #define EIOINTC_VIRT_SIZE (0x1000) 402e8b9df8SXianglai Li 41*3956a52bSXianglai Li #define EIOINTC_VIRT_FEATURES (0x0) 42*3956a52bSXianglai Li #define EIOINTC_HAS_VIRT_EXTENSION (0) 43*3956a52bSXianglai Li #define EIOINTC_HAS_ENABLE_OPTION (1) 44*3956a52bSXianglai Li #define EIOINTC_HAS_INT_ENCODE (2) 45*3956a52bSXianglai Li #define EIOINTC_HAS_CPU_ENCODE (3) 46*3956a52bSXianglai Li #define EIOINTC_VIRT_HAS_FEATURES ((1U << EIOINTC_HAS_VIRT_EXTENSION) \ 47*3956a52bSXianglai Li | (1U << EIOINTC_HAS_ENABLE_OPTION) \ 48*3956a52bSXianglai Li | (1U << EIOINTC_HAS_INT_ENCODE) \ 49*3956a52bSXianglai Li | (1U << EIOINTC_HAS_CPU_ENCODE)) 50*3956a52bSXianglai Li #define EIOINTC_VIRT_CONFIG (0x4) 51*3956a52bSXianglai Li #define EIOINTC_ENABLE (1) 52*3956a52bSXianglai Li #define EIOINTC_ENABLE_INT_ENCODE (2) 53*3956a52bSXianglai Li #define EIOINTC_ENABLE_CPU_ENCODE (3) 54*3956a52bSXianglai Li 552e8b9df8SXianglai Li #define LOONGSON_IP_NUM 8 562e8b9df8SXianglai Li 572e8b9df8SXianglai Li struct loongarch_eiointc { 582e8b9df8SXianglai Li spinlock_t lock; 592e8b9df8SXianglai Li struct kvm *kvm; 602e8b9df8SXianglai Li struct kvm_io_device device; 612e8b9df8SXianglai Li struct kvm_io_device device_vext; 622e8b9df8SXianglai Li uint32_t num_cpu; 632e8b9df8SXianglai Li uint32_t features; 642e8b9df8SXianglai Li uint32_t status; 652e8b9df8SXianglai Li 662e8b9df8SXianglai Li /* hardware state */ 672e8b9df8SXianglai Li union nodetype { 682e8b9df8SXianglai Li u64 reg_u64[EIOINTC_IRQS_NODETYPE_COUNT / 4]; 692e8b9df8SXianglai Li u32 reg_u32[EIOINTC_IRQS_NODETYPE_COUNT / 2]; 702e8b9df8SXianglai Li u16 reg_u16[EIOINTC_IRQS_NODETYPE_COUNT]; 712e8b9df8SXianglai Li u8 reg_u8[EIOINTC_IRQS_NODETYPE_COUNT * 2]; 722e8b9df8SXianglai Li } nodetype; 732e8b9df8SXianglai Li 742e8b9df8SXianglai Li /* one bit shows the state of one irq */ 752e8b9df8SXianglai Li union bounce { 762e8b9df8SXianglai Li u64 reg_u64[EIOINTC_IRQS_U64_NUMS]; 772e8b9df8SXianglai Li u32 reg_u32[EIOINTC_IRQS_U32_NUMS]; 782e8b9df8SXianglai Li u16 reg_u16[EIOINTC_IRQS_U16_NUMS]; 792e8b9df8SXianglai Li u8 reg_u8[EIOINTC_IRQS_U8_NUMS]; 802e8b9df8SXianglai Li } bounce; 812e8b9df8SXianglai Li 822e8b9df8SXianglai Li union isr { 832e8b9df8SXianglai Li u64 reg_u64[EIOINTC_IRQS_U64_NUMS]; 842e8b9df8SXianglai Li u32 reg_u32[EIOINTC_IRQS_U32_NUMS]; 852e8b9df8SXianglai Li u16 reg_u16[EIOINTC_IRQS_U16_NUMS]; 862e8b9df8SXianglai Li u8 reg_u8[EIOINTC_IRQS_U8_NUMS]; 872e8b9df8SXianglai Li } isr; 882e8b9df8SXianglai Li union coreisr { 892e8b9df8SXianglai Li u64 reg_u64[EIOINTC_ROUTE_MAX_VCPUS][EIOINTC_IRQS_U64_NUMS]; 902e8b9df8SXianglai Li u32 reg_u32[EIOINTC_ROUTE_MAX_VCPUS][EIOINTC_IRQS_U32_NUMS]; 912e8b9df8SXianglai Li u16 reg_u16[EIOINTC_ROUTE_MAX_VCPUS][EIOINTC_IRQS_U16_NUMS]; 922e8b9df8SXianglai Li u8 reg_u8[EIOINTC_ROUTE_MAX_VCPUS][EIOINTC_IRQS_U8_NUMS]; 932e8b9df8SXianglai Li } coreisr; 942e8b9df8SXianglai Li union enable { 952e8b9df8SXianglai Li u64 reg_u64[EIOINTC_IRQS_U64_NUMS]; 962e8b9df8SXianglai Li u32 reg_u32[EIOINTC_IRQS_U32_NUMS]; 972e8b9df8SXianglai Li u16 reg_u16[EIOINTC_IRQS_U16_NUMS]; 982e8b9df8SXianglai Li u8 reg_u8[EIOINTC_IRQS_U8_NUMS]; 992e8b9df8SXianglai Li } enable; 1002e8b9df8SXianglai Li 1012e8b9df8SXianglai Li /* use one byte to config ipmap for 32 irqs at once */ 1022e8b9df8SXianglai Li union ipmap { 1032e8b9df8SXianglai Li u64 reg_u64; 1042e8b9df8SXianglai Li u32 reg_u32[EIOINTC_IRQS_U32_NUMS / 4]; 1052e8b9df8SXianglai Li u16 reg_u16[EIOINTC_IRQS_U16_NUMS / 4]; 1062e8b9df8SXianglai Li u8 reg_u8[EIOINTC_IRQS_U8_NUMS / 4]; 1072e8b9df8SXianglai Li } ipmap; 1082e8b9df8SXianglai Li /* use one byte to config coremap for one irq */ 1092e8b9df8SXianglai Li union coremap { 1102e8b9df8SXianglai Li u64 reg_u64[EIOINTC_IRQS / 8]; 1112e8b9df8SXianglai Li u32 reg_u32[EIOINTC_IRQS / 4]; 1122e8b9df8SXianglai Li u16 reg_u16[EIOINTC_IRQS / 2]; 1132e8b9df8SXianglai Li u8 reg_u8[EIOINTC_IRQS]; 1142e8b9df8SXianglai Li } coremap; 1152e8b9df8SXianglai Li 1162e8b9df8SXianglai Li DECLARE_BITMAP(sw_coreisr[EIOINTC_ROUTE_MAX_VCPUS][LOONGSON_IP_NUM], EIOINTC_IRQS); 1172e8b9df8SXianglai Li uint8_t sw_coremap[EIOINTC_IRQS]; 1182e8b9df8SXianglai Li }; 1192e8b9df8SXianglai Li 1202e8b9df8SXianglai Li int kvm_loongarch_register_eiointc_device(void); 121*3956a52bSXianglai Li void eiointc_set_irq(struct loongarch_eiointc *s, int irq, int level); 1222e8b9df8SXianglai Li 1232e8b9df8SXianglai Li #endif /* __ASM_KVM_EIOINTC_H */ 124