1/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2/* 3 * This file is subject to the terms and conditions of the GNU General Public 4 * License. See the file "COPYING" in the main directory of this archive 5 * for more details. 6 * 7 * Copyright (C) 2020 Loongson Technologies, Inc. All rights reserved. 8 * Authors: Sanjay Lal <sanjayl@kymasys.com> 9 * Authors: Xing Li <lixing@loongson.cn> 10 */ 11 12#ifndef __LINUX_KVM_LOONGARCH_H 13#define __LINUX_KVM_LOONGARCH_H 14 15#include <linux/types.h> 16 17#ifndef __KERNEL__ 18#include <stdint.h> 19#endif 20 21#define __KVM_HAVE_GUEST_DEBUG 22#define KVM_GUESTDBG_USE_SW_BP 0x00010000 23#define KVM_GUESTDBG_USE_HW_BP 0x00020000 24#define KVM_DATA_HW_BREAKPOINT_NUM 8 25#define KVM_INST_HW_BREAKPOINT_NUM 8 26 27/* 28 * KVM Loongarch specific structures and definitions. 29 * 30 * Some parts derived from the x86 version of this file. 31 */ 32 33#define __KVM_HAVE_READONLY_MEM 34 35#define KVM_COALESCED_MMIO_PAGE_OFFSET 1 36 37/* 38 * for KVM_GET_REGS and KVM_SET_REGS 39 */ 40struct kvm_regs { 41 /* out (KVM_GET_REGS) / in (KVM_SET_REGS) */ 42 __u64 gpr[32]; 43 __u64 pc; 44}; 45 46/* 47 * for KVM_GET_CPUCFG 48 */ 49struct kvm_cpucfg { 50 /* out (KVM_GET_CPUCFG) */ 51 __u32 cpucfg[64]; 52}; 53 54/* 55 * for KVM_GET_FPU and KVM_SET_FPU 56 */ 57struct kvm_fpu { 58 __u32 fcsr; 59 __u64 fcc; /* 8x8 */ 60 struct kvm_fpureg { 61 __u64 val64[4]; //support max 256 bits 62 } fpr[32]; 63}; 64 65/* 66 * For LOONGARCH, we use KVM_SET_ONE_REG and KVM_GET_ONE_REG to access various 67 * registers. The id field is broken down as follows: 68 * 69 * bits[63..52] - As per linux/kvm.h 70 * bits[51..32] - Must be zero. 71 * bits[31..16] - Register set. 72 * 73 * Register set = 0: GP registers from kvm_regs (see definitions below). 74 * Register set = 1: CSR registers. 75 * Register set = 2: KVM specific registers (see definitions below). 76 * Register set = 3: FPU / SIMD registers (see definitions below). 77 * Register set = 4: LBT registers (see definitions below). 78 * 79 * Other sets registers may be added in the future. Each set would 80 * have its own identifier in bits[31..16]. 81 */ 82 83#define KVM_REG_LOONGARCH_GP (KVM_REG_LOONGARCH | 0x00000ULL) 84#define KVM_REG_LOONGARCH_CSR (KVM_REG_LOONGARCH | 0x10000ULL) 85#define KVM_REG_LOONGARCH_KVM (KVM_REG_LOONGARCH | 0x20000ULL) 86#define KVM_REG_LOONGARCH_FPU (KVM_REG_LOONGARCH | 0x30000ULL) 87#define KVM_REG_LOONGARCH_LBT (KVM_REG_LOONGARCH | 0x40000ULL) 88#define KVM_REG_LOONGARCH_MASK (KVM_REG_LOONGARCH | 0x70000ULL) 89#define KVM_CSR_IDX_MASK (0x10000 - 1) 90 91/* 92 * KVM_REG_LOONGARCH_KVM - KVM specific control registers. 93 */ 94#define KVM_REG_LOONGARCH_COUNTER (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 3) 95#define KVM_REG_LOONGARCH_VCPU_RESET (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 4) 96 97#define KVM_REG_LBT_SCR0 (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 1) 98#define KVM_REG_LBT_SCR1 (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 2) 99#define KVM_REG_LBT_SCR2 (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 3) 100#define KVM_REG_LBT_SCR3 (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 4) 101#define KVM_REG_LBT_FLAGS (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 5) 102#define KVM_REG_LBT_FTOP (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 6) 103 104#define __KVM_HAVE_IRQ_LINE 105 106struct kvm_debug_exit_arch { 107 __u64 era; 108 __u32 fwps; 109 __u32 mwps; 110 __u32 exception; 111}; 112 113/* for KVM_SET_GUEST_DEBUG */ 114struct hw_breakpoint { 115 __u64 addr; 116 __u64 mask; 117 __u32 asid; 118 __u32 ctrl; 119}; 120 121struct kvm_guest_debug_arch { 122 struct hw_breakpoint data_breakpoint[KVM_DATA_HW_BREAKPOINT_NUM]; 123 struct hw_breakpoint inst_breakpoint[KVM_INST_HW_BREAKPOINT_NUM]; 124 int inst_bp_nums, data_bp_nums; 125}; 126 127/* definition of registers in kvm_run */ 128struct kvm_sync_regs { 129}; 130 131/* dummy definition */ 132struct kvm_sregs { 133}; 134 135struct kvm_iocsr_entry { 136 __u32 addr; 137 __u32 pad; 138 __u64 data; 139}; 140 141struct kvm_csr_entry { 142 __u32 index; 143 __u32 reserved; 144 __u64 data; 145}; 146 147/* for KVM_GET_MSRS and KVM_SET_MSRS */ 148struct kvm_msrs { 149 __u32 ncsrs; /* number of msrs in entries */ 150 __u32 pad; 151 152 struct kvm_csr_entry entries[0]; 153}; 154 155struct kvm_loongarch_interrupt { 156 /* in */ 157 __u32 cpu; 158 __u32 irq; 159}; 160 161#define KVM_IRQCHIP_LS7A_IOAPIC 0x0 162#define KVM_IRQCHIP_LS3A_GIPI 0x1 163#define KVM_IRQCHIP_LS3A_HT_IRQ 0x2 164#define KVM_IRQCHIP_LS3A_ROUTE 0x3 165#define KVM_IRQCHIP_LS3A_EXTIRQ 0x4 166#define KVM_IRQCHIP_LS3A_IPMASK 0x5 167#define KVM_NR_IRQCHIPS 1 168#define KVM_IRQCHIP_NUM_PINS 64 169 170#define KVM_MAX_CORES 256 171#define KVM_EXTIOI_IRQS (256) 172#define KVM_EXTIOI_IRQS_BITMAP_SIZE (KVM_EXTIOI_IRQS / 8) 173/* map to ipnum per 32 irqs */ 174#define KVM_EXTIOI_IRQS_IPMAP_SIZE (KVM_EXTIOI_IRQS / 32) 175#define KVM_EXTIOI_IRQS_PER_GROUP 32 176#define KVM_EXTIOI_IRQS_COREMAP_SIZE (KVM_EXTIOI_IRQS) 177#define KVM_EXTIOI_IRQS_NODETYPE_SIZE 16 178 179struct ls7a_ioapic_state { 180 /* 0x000 interrupt id register */ 181 __u64 int_id; 182 /* 0x020 interrupt mask register */ 183 __u64 int_mask; 184 /* 0x040 1=msi */ 185 __u64 htmsi_en; 186 /* 0x060 edge=1 level =0 */ 187 __u64 intedge; 188 /* 0x080 for clean edge int,set 1 clean,set 0 is noused */ 189 __u64 intclr; 190 /* 0x0c0 */ 191 __u64 auto_crtl0; 192 /* 0x0e0 */ 193 __u64 auto_crtl1; 194 /* 0x100 - 0x140 */ 195 __u8 route_entry[64]; 196 /* 0x200 - 0x240 */ 197 __u8 htmsi_vector[64]; 198 /* 0x300 */ 199 __u64 intisr_chip0; 200 /* 0x320 */ 201 __u64 intisr_chip1; 202 /* edge detection */ 203 __u64 last_intirr; 204 /* 0x380 interrupt request register */ 205 __u64 intirr; 206 /* 0x3a0 interrupt service register */ 207 __u64 intisr; 208 /* 0x3e0 interrupt level polarity selection register, 209 * 0 for high level tirgger 210 */ 211 __u64 int_polarity; 212}; 213 214struct loongarch_gipi_single { 215 __u32 status; 216 __u32 en; 217 __u32 set; 218 __u32 clear; 219 __u64 buf[4]; 220}; 221 222struct loongarch_gipiState { 223 struct loongarch_gipi_single core[KVM_MAX_CORES]; 224}; 225 226struct kvm_loongarch_ls3a_extirq_state { 227 union ext_en_r { 228 uint64_t reg_u64[KVM_EXTIOI_IRQS_BITMAP_SIZE / 8]; 229 uint32_t reg_u32[KVM_EXTIOI_IRQS_BITMAP_SIZE / 4]; 230 uint8_t reg_u8[KVM_EXTIOI_IRQS_BITMAP_SIZE]; 231 } ext_en_r; 232 union bounce_r { 233 uint64_t reg_u64[KVM_EXTIOI_IRQS_BITMAP_SIZE / 8]; 234 uint32_t reg_u32[KVM_EXTIOI_IRQS_BITMAP_SIZE / 4]; 235 uint8_t reg_u8[KVM_EXTIOI_IRQS_BITMAP_SIZE]; 236 } bounce_r; 237 union ext_isr_r { 238 uint64_t reg_u64[KVM_EXTIOI_IRQS_BITMAP_SIZE / 8]; 239 uint32_t reg_u32[KVM_EXTIOI_IRQS_BITMAP_SIZE / 4]; 240 uint8_t reg_u8[KVM_EXTIOI_IRQS_BITMAP_SIZE]; 241 } ext_isr_r; 242 union ext_core_isr_r { 243 uint64_t reg_u64[KVM_MAX_CORES][KVM_EXTIOI_IRQS_BITMAP_SIZE / 8]; 244 uint32_t reg_u32[KVM_MAX_CORES][KVM_EXTIOI_IRQS_BITMAP_SIZE / 4]; 245 uint8_t reg_u8[KVM_MAX_CORES][KVM_EXTIOI_IRQS_BITMAP_SIZE]; 246 } ext_core_isr_r; 247 union ip_map_r { 248 uint64_t reg_u64; 249 uint32_t reg_u32[KVM_EXTIOI_IRQS_IPMAP_SIZE / 4]; 250 uint8_t reg_u8[KVM_EXTIOI_IRQS_IPMAP_SIZE]; 251 } ip_map_r; 252 union core_map_r { 253 uint64_t reg_u64[KVM_EXTIOI_IRQS_COREMAP_SIZE / 8]; 254 uint32_t reg_u32[KVM_EXTIOI_IRQS_COREMAP_SIZE / 4]; 255 uint8_t reg_u8[KVM_EXTIOI_IRQS_COREMAP_SIZE]; 256 } core_map_r; 257 union node_type_r { 258 uint64_t reg_u64[KVM_EXTIOI_IRQS_NODETYPE_SIZE / 4]; 259 uint32_t reg_u32[KVM_EXTIOI_IRQS_NODETYPE_SIZE / 2]; 260 uint16_t reg_u16[KVM_EXTIOI_IRQS_NODETYPE_SIZE]; 261 uint8_t reg_u8[KVM_EXTIOI_IRQS_NODETYPE_SIZE * 2]; 262 } node_type_r; 263}; 264 265struct loongarch_kvm_irqchip { 266 __u16 chip_id; 267 __u16 len; 268 __u16 vcpu_id; 269 __u16 reserved; 270 char data[0]; 271}; 272 273#endif /* __LINUX_KVM_LOONGARCH_H */ 274