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_NODETYPE_START 0xa0 24 #define EIOINTC_NODETYPE_END 0xbf 25 #define EIOINTC_IPMAP_START 0xc0 26 #define EIOINTC_IPMAP_END 0xc7 27 #define EIOINTC_ENABLE_START 0x200 28 #define EIOINTC_ENABLE_END 0x21f 29 #define EIOINTC_BOUNCE_START 0x280 30 #define EIOINTC_BOUNCE_END 0x29f 31 #define EIOINTC_ISR_START 0x300 32 #define EIOINTC_ISR_END 0x31f 33 #define EIOINTC_COREISR_START 0x400 34 #define EIOINTC_COREISR_END 0x41f 35 #define EIOINTC_COREMAP_START 0x800 36 #define EIOINTC_COREMAP_END 0x8ff 37 38 #define EIOINTC_VIRT_BASE (0x40000000) 39 #define EIOINTC_VIRT_SIZE (0x1000) 40 41 #define EIOINTC_VIRT_FEATURES (0x0) 42 #define EIOINTC_HAS_VIRT_EXTENSION (0) 43 #define EIOINTC_HAS_ENABLE_OPTION (1) 44 #define EIOINTC_HAS_INT_ENCODE (2) 45 #define EIOINTC_HAS_CPU_ENCODE (3) 46 #define EIOINTC_VIRT_HAS_FEATURES ((1U << EIOINTC_HAS_VIRT_EXTENSION) \ 47 | (1U << EIOINTC_HAS_ENABLE_OPTION) \ 48 | (1U << EIOINTC_HAS_INT_ENCODE) \ 49 | (1U << EIOINTC_HAS_CPU_ENCODE)) 50 #define EIOINTC_VIRT_CONFIG (0x4) 51 #define EIOINTC_ENABLE (1) 52 #define EIOINTC_ENABLE_INT_ENCODE (2) 53 #define EIOINTC_ENABLE_CPU_ENCODE (3) 54 55 #define LOONGSON_IP_NUM 8 56 57 struct loongarch_eiointc { 58 spinlock_t lock; 59 struct kvm *kvm; 60 struct kvm_io_device device; 61 struct kvm_io_device device_vext; 62 uint32_t num_cpu; 63 uint32_t features; 64 uint32_t status; 65 66 /* hardware state */ 67 union nodetype { 68 u64 reg_u64[EIOINTC_IRQS_NODETYPE_COUNT / 4]; 69 u32 reg_u32[EIOINTC_IRQS_NODETYPE_COUNT / 2]; 70 u16 reg_u16[EIOINTC_IRQS_NODETYPE_COUNT]; 71 u8 reg_u8[EIOINTC_IRQS_NODETYPE_COUNT * 2]; 72 } nodetype; 73 74 /* one bit shows the state of one irq */ 75 union bounce { 76 u64 reg_u64[EIOINTC_IRQS_U64_NUMS]; 77 u32 reg_u32[EIOINTC_IRQS_U32_NUMS]; 78 u16 reg_u16[EIOINTC_IRQS_U16_NUMS]; 79 u8 reg_u8[EIOINTC_IRQS_U8_NUMS]; 80 } bounce; 81 82 union isr { 83 u64 reg_u64[EIOINTC_IRQS_U64_NUMS]; 84 u32 reg_u32[EIOINTC_IRQS_U32_NUMS]; 85 u16 reg_u16[EIOINTC_IRQS_U16_NUMS]; 86 u8 reg_u8[EIOINTC_IRQS_U8_NUMS]; 87 } isr; 88 union coreisr { 89 u64 reg_u64[EIOINTC_ROUTE_MAX_VCPUS][EIOINTC_IRQS_U64_NUMS]; 90 u32 reg_u32[EIOINTC_ROUTE_MAX_VCPUS][EIOINTC_IRQS_U32_NUMS]; 91 u16 reg_u16[EIOINTC_ROUTE_MAX_VCPUS][EIOINTC_IRQS_U16_NUMS]; 92 u8 reg_u8[EIOINTC_ROUTE_MAX_VCPUS][EIOINTC_IRQS_U8_NUMS]; 93 } coreisr; 94 union enable { 95 u64 reg_u64[EIOINTC_IRQS_U64_NUMS]; 96 u32 reg_u32[EIOINTC_IRQS_U32_NUMS]; 97 u16 reg_u16[EIOINTC_IRQS_U16_NUMS]; 98 u8 reg_u8[EIOINTC_IRQS_U8_NUMS]; 99 } enable; 100 101 /* use one byte to config ipmap for 32 irqs at once */ 102 union ipmap { 103 u64 reg_u64; 104 u32 reg_u32[EIOINTC_IRQS_U32_NUMS / 4]; 105 u16 reg_u16[EIOINTC_IRQS_U16_NUMS / 4]; 106 u8 reg_u8[EIOINTC_IRQS_U8_NUMS / 4]; 107 } ipmap; 108 /* use one byte to config coremap for one irq */ 109 union coremap { 110 u64 reg_u64[EIOINTC_IRQS / 8]; 111 u32 reg_u32[EIOINTC_IRQS / 4]; 112 u16 reg_u16[EIOINTC_IRQS / 2]; 113 u8 reg_u8[EIOINTC_IRQS]; 114 } coremap; 115 116 DECLARE_BITMAP(sw_coreisr[EIOINTC_ROUTE_MAX_VCPUS][LOONGSON_IP_NUM], EIOINTC_IRQS); 117 uint8_t sw_coremap[EIOINTC_IRQS]; 118 }; 119 120 int kvm_loongarch_register_eiointc_device(void); 121 void eiointc_set_irq(struct loongarch_eiointc *s, int irq, int level); 122 123 #endif /* __ASM_KVM_EIOINTC_H */ 124