1 // 2 // Copyright (c) 2010-2021 Antmicro 3 // 4 // This file is licensed under the MIT License. 5 // Full license text is available in 'licenses/MIT.txt'. 6 // 7 using System; 8 using System.Collections.Generic; 9 10 namespace Antmicro.Renode.Peripherals.CPU 11 { 12 // Those methods use RiscV32Registers enum and assume those values are also valid for rv64 13 public static class RiscVRegisterDescription 14 { AddCpuFeature(ref List<GDBFeatureDescriptor> features, uint registerWidth)15 public static void AddCpuFeature(ref List<GDBFeatureDescriptor> features, uint registerWidth) 16 { 17 var cpuGroup = new GDBFeatureDescriptor("org.gnu.gdb.riscv.cpu"); 18 var intType = $"uint{registerWidth}"; 19 20 for(var index = 0u; index < NumberOfXRegisters; ++index) 21 { 22 cpuGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.X0 + index, registerWidth, $"x{index}", intType, "general")); 23 } 24 25 cpuGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.PC, registerWidth, "pc", "code_ptr", "general")); 26 features.Add(cpuGroup); 27 } 28 AddFpuFeature(ref List<GDBFeatureDescriptor> features, uint registerWidth, bool extensionH, bool extensionF, bool extensionD, bool extensionQ)29 public static void AddFpuFeature(ref List<GDBFeatureDescriptor> features, uint registerWidth, bool extensionH, bool extensionF, bool extensionD, bool extensionQ) 30 { 31 if(!(extensionH || extensionF || extensionD || extensionQ)) 32 { 33 return; 34 } 35 36 var fpuGroup = new GDBFeatureDescriptor("org.gnu.gdb.riscv.fpu"); 37 var intType = $"uint{registerWidth}"; 38 var fWidth = 0u; 39 var types = new List<string>(); 40 41 if(extensionH) 42 { 43 fWidth = 16u; 44 types.Add("half"); 45 46 var fields = new List<GDBTypeBitField>(); 47 fields.Add(new GDBTypeBitField("sign", 15, 15, "uint16")); 48 fields.Add(new GDBTypeBitField("exponent", 10, 14, "uint16")); 49 fields.Add(new GDBTypeBitField("fraction", 0, 9, "uint16")); 50 var half = GDBCustomType.Struct("half", fWidth / 8, fields); 51 fpuGroup.Types.Add(half); 52 } 53 if(extensionF) 54 { 55 fWidth = 32u; 56 types.Add("single"); 57 } 58 if(extensionD) 59 { 60 fWidth = 64u; 61 types.Add("double"); 62 } 63 if(extensionQ) 64 { 65 fWidth = 128u; 66 types.Add("quad"); 67 68 var fields = new List<GDBTypeBitField>(); 69 fields.Add(new GDBTypeBitField("sign", 127, 127, "uint128")); 70 fields.Add(new GDBTypeBitField("exponent", 112, 126, "uint128")); 71 fields.Add(new GDBTypeBitField("fraction", 0, 111, "uint128")); 72 var quad = GDBCustomType.Struct("quad", fWidth / 8, fields); 73 fpuGroup.Types.Add(quad); 74 } 75 76 var floatType = $"ieee_{types[0]}"; 77 // If there's more than one float type then they're combined with union 78 // narrower type is in the lowest part of the wider ones, specification calls it NaN-boxing model. 79 if(types.Count > 1) 80 { 81 floatType = "nan_boxed_float"; 82 var fields = new List<GDBTypeField>(); 83 foreach(var type in types) 84 { 85 fields.Add(new GDBTypeField(type, $"ieee_{type}")); 86 } 87 var nanBoxedFloat = GDBCustomType.Union(floatType, fields); 88 fpuGroup.Types.Add(nanBoxedFloat); 89 } 90 91 for(var index = 0u; index < NumberOfFRegisters; ++index) 92 { 93 fpuGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.F0 + index, fWidth, $"f{index}", floatType, "float")); 94 } 95 96 // fflags, frm and fcsr are not implemented but are required for architecture description 97 var fflagsIndex = (uint)RiscV32Registers.F0 + NumberOfFRegisters; 98 fpuGroup.Registers.Add(new GDBRegisterDescriptor(fflagsIndex, registerWidth, "fflags", "", "float")); 99 fpuGroup.Registers.Add(new GDBRegisterDescriptor(fflagsIndex + 1, registerWidth, "frm", "", "float")); 100 fpuGroup.Registers.Add(new GDBRegisterDescriptor(fflagsIndex + 2, registerWidth, "fcsr", "", "float")); 101 102 { 103 var fields = new List<GDBTypeBitField>(); 104 fields.Add(new GDBTypeBitField("NX", 0, 0, "bool")); 105 fields.Add(new GDBTypeBitField("UF", 1, 1, "bool")); 106 fields.Add(new GDBTypeBitField("OF", 2, 2, "bool")); 107 fields.Add(new GDBTypeBitField("DZ", 3, 3, "bool")); 108 fields.Add(new GDBTypeBitField("NV", 4, 4, "bool")); 109 var fflagsFlagsType = GDBCustomType.Flags("fflags_flags_type", 1, fields); 110 fpuGroup.Types.Add(fflagsFlagsType); 111 } 112 { 113 var fields = new List<GDBTypeEnumValue>(); 114 fields.Add(new GDBTypeEnumValue("RNE", 0b000)); 115 fields.Add(new GDBTypeEnumValue("RTZ", 0b001)); 116 fields.Add(new GDBTypeEnumValue("RDN", 0b010)); 117 fields.Add(new GDBTypeEnumValue("RUP", 0b011)); 118 fields.Add(new GDBTypeEnumValue("RMM", 0b100)); 119 fields.Add(new GDBTypeEnumValue("DYN", 0b111)); 120 var frmEnumType = GDBCustomType.Enum("frm_enum_type", 1, fields); 121 fpuGroup.Types.Add(frmEnumType); 122 } 123 { 124 var fields = new List<GDBTypeBitField>(); 125 fields.Add(new GDBTypeBitField("value", 0, 4, "fflags_flags_type")); 126 var fflagsType = GDBCustomType.Struct("fflags_type", registerWidth / 8, fields); 127 fpuGroup.Types.Add(fflagsType); 128 } 129 { 130 var fields = new List<GDBTypeBitField>(); 131 fields.Add(new GDBTypeBitField("value", 0, 5, "frm_enum_type")); 132 var frmType = GDBCustomType.Struct("frm_type", registerWidth / 8, fields); 133 fpuGroup.Types.Add(frmType); 134 } 135 { 136 var fields = new List<GDBTypeBitField>(); 137 fields.Add(new GDBTypeBitField("flags", 0, 4, "fflags_flags_type")); 138 fields.Add(new GDBTypeBitField("rm", 5, 7, "frm_enum_type")); 139 var fcsrType = GDBCustomType.Struct("fcsr_type", registerWidth / 8, fields); 140 fpuGroup.Types.Add(fcsrType); 141 } 142 143 features.Add(fpuGroup); 144 } 145 AddCSRFeature(ref List<GDBFeatureDescriptor> features, uint registerWidth, bool extensionS, bool extensionU, bool extensionN, bool extensionV)146 public static void AddCSRFeature(ref List<GDBFeatureDescriptor> features, uint registerWidth, bool extensionS, bool extensionU, bool extensionN, bool extensionV) 147 { 148 var csrGroup = new GDBFeatureDescriptor("org.gnu.gdb.riscv.csr"); 149 var intType = $"uint{registerWidth}"; 150 151 { 152 var fields = new List<GDBTypeEnumValue>(); 153 fields.Add(new GDBTypeEnumValue("32", 1)); 154 fields.Add(new GDBTypeEnumValue("64", 2)); 155 fields.Add(new GDBTypeEnumValue("128", 3)); 156 var misaMxlType = GDBCustomType.Enum("xl_type", 2, fields); 157 csrGroup.Types.Add(misaMxlType); 158 } 159 { 160 var fields = new List<GDBTypeEnumValue>(); 161 fields.Add(new GDBTypeEnumValue("All off", 0)); 162 fields.Add(new GDBTypeEnumValue("None dirty or clean, some on", 1)); 163 fields.Add(new GDBTypeEnumValue("None dirty, some clean", 2)); 164 fields.Add(new GDBTypeEnumValue("Some dirty", 3)); 165 var xsType = GDBCustomType.Enum("xs_type", 1, fields); 166 csrGroup.Types.Add(xsType); 167 } 168 { 169 var fields = new List<GDBTypeEnumValue>(); 170 fields.Add(new GDBTypeEnumValue("Off", 0)); 171 fields.Add(new GDBTypeEnumValue("Initial", 1)); 172 fields.Add(new GDBTypeEnumValue("Clean", 2)); 173 fields.Add(new GDBTypeEnumValue("Dirty", 3)); 174 var fsType = GDBCustomType.Enum("fs_type", 1, fields); 175 csrGroup.Types.Add(fsType); 176 } 177 { 178 var fields = new List<GDBTypeEnumValue>(); 179 fields.Add(new GDBTypeEnumValue("U", 0b00)); 180 fields.Add(new GDBTypeEnumValue("S", 0b01)); 181 fields.Add(new GDBTypeEnumValue("M", 0b11)); 182 var privType = GDBCustomType.Enum("priv_type", 1, fields); 183 csrGroup.Types.Add(privType); 184 } 185 { 186 var fields = new List<GDBTypeEnumValue>(); 187 fields.Add(new GDBTypeEnumValue("Off", 0)); 188 fields.Add(new GDBTypeEnumValue("Initial", 1)); 189 fields.Add(new GDBTypeEnumValue("Clean", 2)); 190 fields.Add(new GDBTypeEnumValue("Dirty", 3)); 191 var vsType = GDBCustomType.Enum("vs_type", 1, fields); 192 csrGroup.Types.Add(vsType); 193 } 194 { 195 var fields = new List<GDBTypeBitField>(); 196 fields.Add(new GDBTypeBitField("UIE", 0, 0, "bool")); 197 fields.Add(new GDBTypeBitField("SIE", 1, 1, "bool")); 198 fields.Add(new GDBTypeBitField("MIE", 3, 3, "bool")); 199 fields.Add(new GDBTypeBitField("UPIE", 4, 4, "bool")); 200 fields.Add(new GDBTypeBitField("SPIE", 5, 5, "bool")); 201 fields.Add(new GDBTypeBitField("MPIE", 7, 7, "bool")); 202 fields.Add(new GDBTypeBitField("SPP", 8, 8, "priv_type")); 203 fields.Add(new GDBTypeBitField("VS", 9, 10, "vs_type")); 204 fields.Add(new GDBTypeBitField("MPP", 11, 12, "priv_type")); 205 fields.Add(new GDBTypeBitField("FS", 13, 14, "fs_type")); 206 fields.Add(new GDBTypeBitField("XS", 15, 16, "xs_type")); 207 fields.Add(new GDBTypeBitField("MPRIV", 17, 17, "bool")); 208 fields.Add(new GDBTypeBitField("SUM", 18, 18, "bool")); 209 fields.Add(new GDBTypeBitField("MXR", 19, 19, "bool")); 210 fields.Add(new GDBTypeBitField("TVM", 20, 20, "bool")); 211 fields.Add(new GDBTypeBitField("TW", 21, 21, "bool")); 212 fields.Add(new GDBTypeBitField("TSR", 22, 22, "bool")); 213 if(registerWidth == 32) 214 { 215 fields.Add(new GDBTypeBitField("SD", 31, 31, "bool")); 216 } 217 else if(registerWidth == 64) 218 { 219 fields.Add(new GDBTypeBitField("UXL", 32, 33, "xl_type")); 220 fields.Add(new GDBTypeBitField("SXL", 34, 35, "xl_type")); 221 fields.Add(new GDBTypeBitField("SD", 63, 63, "boolc")); 222 } 223 else 224 { 225 throw new NotImplementedException($"There is no type definition for MSTATUS with register width {registerWidth}."); 226 } 227 var mstatusType = GDBCustomType.Struct("mstatus_type", registerWidth / 8, fields); 228 csrGroup.Types.Add(mstatusType); 229 } 230 { 231 var fields = new List<GDBTypeBitField>(); 232 for(var c = 'A'; c <= 'Z'; ++c) 233 { 234 var index = (uint)(c - 'A'); 235 fields.Add(new GDBTypeBitField($"{c}", index, index, "bool")); 236 } 237 var misaExtensionsType = GDBCustomType.Flags("misa_extensions_type", 4, fields); 238 csrGroup.Types.Add(misaExtensionsType); 239 } 240 { 241 var fields = new List<GDBTypeBitField>(); 242 fields.Add(new GDBTypeBitField("MXL", registerWidth - 2, registerWidth - 1, "xl_type")); 243 fields.Add(new GDBTypeBitField("Extensions", 0, 25, "misa_extensions_type")); 244 var misaType = GDBCustomType.Struct("misa_type", registerWidth / 8, fields); 245 csrGroup.Types.Add(misaType); 246 } 247 { 248 var fields = new List<GDBTypeBitField>(); 249 fields.Add(new GDBTypeBitField("USIP", 0, 0, "bool")); 250 fields.Add(new GDBTypeBitField("SSIP", 1, 1, "bool")); 251 fields.Add(new GDBTypeBitField("MSIP", 3, 3, "bool")); 252 fields.Add(new GDBTypeBitField("UTIP", 4, 4, "bool")); 253 fields.Add(new GDBTypeBitField("STIP", 5, 5, "bool")); 254 fields.Add(new GDBTypeBitField("MTIP", 7, 7, "bool")); 255 fields.Add(new GDBTypeBitField("UEIP", 8, 8, "bool")); 256 fields.Add(new GDBTypeBitField("SEIP", 9, 9, "bool")); 257 fields.Add(new GDBTypeBitField("MEIP", 11, 11, "bool")); 258 var mipType = GDBCustomType.Flags("mip_type", registerWidth / 8, fields); 259 csrGroup.Types.Add(mipType); 260 } 261 { 262 var fields = new List<GDBTypeBitField>(); 263 fields.Add(new GDBTypeBitField("USIE", 0, 0, "bool")); 264 fields.Add(new GDBTypeBitField("SSIE", 1, 1, "bool")); 265 fields.Add(new GDBTypeBitField("MSIE", 3, 3, "bool")); 266 fields.Add(new GDBTypeBitField("UTIE", 4, 4, "bool")); 267 fields.Add(new GDBTypeBitField("STIE", 5, 5, "bool")); 268 fields.Add(new GDBTypeBitField("MTIE", 7, 7, "bool")); 269 fields.Add(new GDBTypeBitField("UEIE", 8, 8, "bool")); 270 fields.Add(new GDBTypeBitField("SEIE", 9, 9, "bool")); 271 fields.Add(new GDBTypeBitField("MEIE", 11, 11, "bool")); 272 var mieType = GDBCustomType.Flags("mie_type", registerWidth / 8, fields); 273 csrGroup.Types.Add(mieType); 274 } 275 { 276 var fields = new List<GDBTypeEnumValue>(); 277 fields.Add(new GDBTypeEnumValue("Direct", 0)); 278 fields.Add(new GDBTypeEnumValue("Vectored", 1)); 279 var mtvecModeType = GDBCustomType.Enum("tvec_mode_type", 1, fields); 280 csrGroup.Types.Add(mtvecModeType); 281 } 282 { 283 var fields = new List<GDBTypeBitField>(); 284 fields.Add(new GDBTypeBitField("MODE", 0, 1, "tvec_mode_type")); 285 fields.Add(new GDBTypeBitField("BASE", 2, registerWidth - 1, "code_ptr")); 286 var tvecType = GDBCustomType.Struct("tvec_type", registerWidth / 8, fields); 287 csrGroup.Types.Add(tvecType); 288 } 289 { 290 var fields = new List<GDBTypeBitField>(); 291 fields.Add(new GDBTypeBitField("Interrupt", registerWidth - 1, registerWidth - 1, "bool")); 292 fields.Add(new GDBTypeBitField("Exception Code", 0, registerWidth - 2, intType)); 293 var mcauseType = GDBCustomType.Struct("cause_type", registerWidth / 8, fields); 294 csrGroup.Types.Add(mcauseType); 295 } 296 297 if(extensionS) 298 { 299 { 300 var fields = new List<GDBTypeBitField>(); 301 fields.Add(new GDBTypeBitField("UIE", 0, 0, "bool")); 302 fields.Add(new GDBTypeBitField("SIE", 1, 1, "bool")); 303 fields.Add(new GDBTypeBitField("UPIE", 4, 4, "bool")); 304 fields.Add(new GDBTypeBitField("SPIE", 5, 5, "bool")); 305 fields.Add(new GDBTypeBitField("SPP", 8, 8, "priv_type")); 306 fields.Add(new GDBTypeBitField("FS", 13, 14, "fs_type")); 307 fields.Add(new GDBTypeBitField("XS", 15, 16, "xs_type")); 308 fields.Add(new GDBTypeBitField("SUM", 18, 18, "bool")); 309 fields.Add(new GDBTypeBitField("MXR", 19, 19, "bool")); 310 if(registerWidth == 32) 311 { 312 fields.Add(new GDBTypeBitField("SD", 31, 31, "bool")); 313 } 314 else if(registerWidth == 64) 315 { 316 fields.Add(new GDBTypeBitField("UXL", 32, 33, "xl_type")); 317 fields.Add(new GDBTypeBitField("SD", 63, 63, "boolc")); 318 } 319 else 320 { 321 throw new NotImplementedException($"There is no type definition for SSTATUS with register width {registerWidth}."); 322 } 323 var sstatusType = GDBCustomType.Struct("sstatus_type", registerWidth / 8, fields); 324 csrGroup.Types.Add(sstatusType); 325 } 326 { 327 var fields = new List<GDBTypeBitField>(); 328 fields.Add(new GDBTypeBitField("USIP", 0, 0, "bool")); 329 fields.Add(new GDBTypeBitField("SSIP", 1, 1, "bool")); 330 fields.Add(new GDBTypeBitField("UTIP", 4, 4, "bool")); 331 fields.Add(new GDBTypeBitField("STIP", 5, 5, "bool")); 332 fields.Add(new GDBTypeBitField("UEIP", 8, 8, "bool")); 333 fields.Add(new GDBTypeBitField("SEIP", 9, 9, "bool")); 334 var sipType = GDBCustomType.Flags("sip_type", registerWidth / 8, fields); 335 csrGroup.Types.Add(sipType); 336 } 337 { 338 var fields = new List<GDBTypeBitField>(); 339 fields.Add(new GDBTypeBitField("USIE", 0, 0, "bool")); 340 fields.Add(new GDBTypeBitField("SSIE", 1, 1, "bool")); 341 fields.Add(new GDBTypeBitField("UTIE", 4, 4, "bool")); 342 fields.Add(new GDBTypeBitField("STIE", 5, 5, "bool")); 343 fields.Add(new GDBTypeBitField("UEIE", 8, 8, "bool")); 344 fields.Add(new GDBTypeBitField("SEIE", 9, 9, "bool")); 345 var sieType = GDBCustomType.Flags("sie_type", registerWidth / 8, fields); 346 csrGroup.Types.Add(sieType); 347 } 348 { 349 var fields = new List<GDBTypeEnumValue>(); 350 fields.Add(new GDBTypeEnumValue("Bare", 0)); 351 fields.Add(new GDBTypeEnumValue("Sv32", 1)); 352 fields.Add(new GDBTypeEnumValue("Sv39", 8)); 353 fields.Add(new GDBTypeEnumValue("Sv48", 9)); 354 fields.Add(new GDBTypeEnumValue("Sv57", 10)); 355 fields.Add(new GDBTypeEnumValue("Sv64", 11)); 356 var satpModeType = GDBCustomType.Enum("satp_mode_type", 1, fields); 357 csrGroup.Types.Add(satpModeType); 358 } 359 { 360 var fields = new List<GDBTypeBitField>(); 361 if(registerWidth == 32) 362 { 363 fields.Add(new GDBTypeBitField("PPN", 0, 21, "data_ptr")); 364 fields.Add(new GDBTypeBitField("ASID", 22, 30, "data_ptr")); 365 fields.Add(new GDBTypeBitField("MODE", 31, 31, "satp_mode_type")); 366 } 367 else if(registerWidth == 64) 368 { 369 fields.Add(new GDBTypeBitField("PPN", 0, 43, "data_ptr")); 370 fields.Add(new GDBTypeBitField("ASID", 44, 59, "data_ptr")); 371 fields.Add(new GDBTypeBitField("MODE", 60, 63, "satp_mode_type")); 372 } 373 else 374 { 375 throw new NotImplementedException($"There is no type definition for SATP with register width {registerWidth}."); 376 } 377 var satpType = GDBCustomType.Struct("satp_type", registerWidth / 8, fields); 378 csrGroup.Types.Add(satpType); 379 } 380 381 csrGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.SSTATUS, registerWidth, "sstatus", "sstatus_type", "csr")); 382 csrGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.SIE, registerWidth, "sie", "sie_type", "csr")); 383 csrGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.SIP, registerWidth, "sip", "sip_type", "csr")); 384 csrGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.STVEC, registerWidth, "stvec", "tvec_type", "csr")); 385 csrGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.SSCRATCH, registerWidth, "sscratch", "data_ptr", "csr")); 386 csrGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.SEPC, registerWidth, "sepc", "code_ptr", "csr")); 387 csrGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.SCAUSE, registerWidth, "scause", "cause_type", "csr")); 388 csrGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.STVAL, registerWidth, "stval", intType, "csr")); 389 csrGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.SATP, registerWidth, "satp", "satp_type", "csr")); 390 } 391 if(extensionS || (extensionU && extensionN)) 392 { 393 csrGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.MEDELEG, registerWidth, "medeleg", intType, "csr")); 394 csrGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.MIDELEG, registerWidth, "mideleg", intType, "csr")); 395 } 396 397 csrGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.MSTATUS, registerWidth, "mstatus", "", "csr")); 398 csrGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.MISA, registerWidth, "misa", "", "csr")); 399 csrGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.MIE, registerWidth, "mie", "mie_type", "csr")); 400 csrGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.MIP, registerWidth, "mip", "mip_type", "csr")); 401 csrGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.MTVEC, registerWidth, "mtvec", "tvec_type", "csr")); 402 csrGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.MSCRATCH, registerWidth, "mscratch", "data_ptr", "csr")); 403 csrGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.MEPC, registerWidth, "mepc", "code_ptr", "csr")); 404 csrGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.MCAUSE, registerWidth, "mcause", "cause_type", "csr")); 405 csrGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.MTVAL, registerWidth, "mtval", intType, "csr")); 406 407 if(extensionV) 408 { 409 csrGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.VSTART, registerWidth, "vstart", group: "vector")); 410 csrGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.VXSAT, registerWidth, "vxsat", group: "vector")); 411 csrGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.VXRM, registerWidth, "vxrm", group: "vector")); 412 csrGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.VCSR, registerWidth, "vcsr", group: "vector")); 413 csrGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.VL, registerWidth, "vl", group: "vector")); 414 csrGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.VTYPE, registerWidth, "vtype", group: "vector")); 415 csrGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.VLENB, registerWidth, "vlenb", group: "vector")); 416 } 417 418 features.Add(csrGroup); 419 } 420 AddVirtualFeature(ref List<GDBFeatureDescriptor> features, uint registerWidth)421 public static void AddVirtualFeature(ref List<GDBFeatureDescriptor> features, uint registerWidth) 422 { 423 var virtualGroup = new GDBFeatureDescriptor("org.gnu.gdb.riscv.virtual"); 424 { 425 var fields = new List<GDBTypeEnumValue>(); 426 fields.Add(new GDBTypeEnumValue("User/Application", 0b00)); 427 fields.Add(new GDBTypeEnumValue("Supervisor", 0b01)); 428 fields.Add(new GDBTypeEnumValue("Machine", 0b11)); 429 var privType = GDBCustomType.Enum("priv_type", 1, fields); 430 virtualGroup.Types.Add(privType); 431 } 432 virtualGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.PRIV, registerWidth, "priv", "priv_type", "virtual")); 433 features.Add(virtualGroup); 434 } 435 AddCustomCSRFeature(ref List<GDBFeatureDescriptor> features, uint registerWidth, IReadOnlyDictionary<ulong, NonstandardCSR> customRegisters)436 public static void AddCustomCSRFeature(ref List<GDBFeatureDescriptor> features, uint registerWidth, IReadOnlyDictionary<ulong, NonstandardCSR> customRegisters) 437 { 438 var customCSRGroup = new GDBFeatureDescriptor("org.gnu.gdb.riscv.custom-csr"); 439 var intType = $"uint{registerWidth}"; 440 441 foreach(var customRegister in customRegisters) 442 { 443 var name = customRegister.Value.Name; 444 if(name != null) 445 { 446 var number = (uint)customRegister.Key; 447 customCSRGroup.Registers.Add(new GDBRegisterDescriptor(number, registerWidth, name, intType, "custom-csr")); 448 } 449 } 450 451 features.Add(customCSRGroup); 452 } 453 AddVectorFeature(ref List<GDBFeatureDescriptor> features, uint registerWidth)454 public static void AddVectorFeature(ref List<GDBFeatureDescriptor> features, uint registerWidth) 455 { 456 var vectorGroup = new GDBFeatureDescriptor("org.gnu.gdb.riscv.vector"); 457 458 var riscvVectorTypeFields = new List<GDBTypeField>(); 459 460 if(registerWidth / 128 > 0) 461 { 462 var vu128TypeID = $"vector_u128_{registerWidth / 128}"; 463 var vu128Type = GDBCustomType.Vector(vu128TypeID, "uint128", registerWidth / 128); 464 vectorGroup.Types.Add(vu128Type); 465 riscvVectorTypeFields.Add(new GDBTypeField("q", vu128TypeID)); 466 } 467 468 if(registerWidth / 64 > 0) 469 { 470 var vu64TypeID = $"vector_u64_{registerWidth / 64}"; 471 var vu64Type = GDBCustomType.Vector(vu64TypeID, "uint64", registerWidth / 64); 472 vectorGroup.Types.Add(vu64Type); 473 riscvVectorTypeFields.Add(new GDBTypeField("l", vu64TypeID)); 474 } 475 476 if(registerWidth / 32 > 0) 477 { 478 var vu32TypeID = $"vector_u32_{registerWidth / 32}"; 479 var vu32Type = GDBCustomType.Vector(vu32TypeID, "uint32", registerWidth / 32); 480 vectorGroup.Types.Add(vu32Type); 481 riscvVectorTypeFields.Add(new GDBTypeField("w", vu32TypeID)); 482 } 483 484 if(registerWidth / 16 > 0) 485 { 486 var vu16TypeID = $"vector_u16_{registerWidth / 16}"; 487 var vu16Type = GDBCustomType.Vector(vu16TypeID, "uint16", registerWidth / 16); 488 vectorGroup.Types.Add(vu16Type); 489 riscvVectorTypeFields.Add(new GDBTypeField("s", vu16TypeID)); 490 } 491 492 if(registerWidth / 8 > 0) 493 { 494 var vu8TypeID = $"vector_u8_{registerWidth / 8}"; 495 var vu8Type = GDBCustomType.Vector(vu8TypeID, "uint8", registerWidth / 8); 496 vectorGroup.Types.Add(vu8Type); 497 riscvVectorTypeFields.Add(new GDBTypeField("b", vu8TypeID)); 498 } 499 500 var riscvVectorType = GDBCustomType.Union("riscv_vector", riscvVectorTypeFields); 501 vectorGroup.Types.Add(riscvVectorType); 502 503 for(var index = 0u; index < NumberOfVRegisters; ++index) 504 { 505 vectorGroup.Registers.Add(new GDBRegisterDescriptor(StartOfVRegisters + index, registerWidth, $"v{index}", "riscv_vector", "vector")); 506 } 507 508 features.Add(vectorGroup); 509 } 510 511 public const uint NumberOfXRegisters = 32; 512 public const uint NumberOfFRegisters = 32; 513 public const uint NumberOfAdditionalFRegisters = 3; 514 public const uint StartOfVRegisters = 68; 515 public const uint NumberOfVRegisters = 32; 516 } 517 } 518