1 // 2 // Copyright (c) 2010-2024 Antmicro 3 // 4 // This file is licensed under the MIT License. 5 // Full license text is available in 'licenses/MIT.txt'. 6 // 7 8 using System; 9 using System.Linq; 10 using System.Text; 11 using Antmicro.Renode.Core; 12 using Antmicro.Renode.Peripherals.Bus; 13 using Antmicro.Renode.Time; 14 using Antmicro.Renode.Exceptions; 15 using Antmicro.Renode.Utilities; 16 using System.Collections.Generic; 17 18 namespace Antmicro.Renode.Peripherals.CPU 19 { 20 public interface ICPUWithRegisters : ICPU 21 { SetRegister(int register, RegisterValue value)22 void SetRegister(int register, RegisterValue value); GetRegister(int register)23 RegisterValue GetRegister(int register); GetRegisters()24 IEnumerable<CPURegister> GetRegisters(); 25 } 26 27 public static class ICPUWithRegistersExtensions 28 { 29 // this is to support Python integration GetRegisterUlong(this ICPUWithRegisters cpu, int register)30 public static ulong GetRegisterUlong(this ICPUWithRegisters cpu, int register) 31 { 32 return cpu.GetRegister(register).RawValue; 33 } 34 GetRegisterUlong(this ICPUWithRegisters cpu, string register)35 public static ulong GetRegisterUlong(this ICPUWithRegisters cpu, string register) 36 { 37 return cpu.GetRegister(register).RawValue; 38 } 39 SetRegisterUlong(this ICPUWithRegisters cpu, int register, ulong value)40 public static void SetRegisterUlong(this ICPUWithRegisters cpu, int register, ulong value) 41 { 42 cpu.SetRegister(register, value); 43 } 44 SetRegisterUlong(this ICPUWithRegisters cpu, string register, ulong value)45 public static void SetRegisterUlong(this ICPUWithRegisters cpu, string register, ulong value) 46 { 47 cpu.SetRegister(register, value); 48 } 49 SetRegister(this ICPUWithRegisters cpu, string register, RegisterValue value)50 public static void SetRegister(this ICPUWithRegisters cpu, string register, RegisterValue value) 51 { 52 // for dynamically added registers (e.g., V ones for RISC-V) it's possible for `Alias` to be null; 53 // this needs to be investigated, but for now let's just filter such situations out 54 var reg = cpu.GetRegisters().FirstOrDefault(x => x.Aliases != null && x.Aliases.Contains(register)); 55 // `reg` is a struct so it'll never be `null` 56 if(reg.Aliases == null) 57 { 58 throw new RecoverableException($"Wrong register name: {register}"); 59 } 60 cpu.SetRegister(reg.Index, value); 61 } 62 GetRegister(this ICPUWithRegisters cpu, string register)63 public static RegisterValue GetRegister(this ICPUWithRegisters cpu, string register) 64 { 65 // for dynamically added registers (e.g., V ones for RISC-V) it's possible for `Alias` to be null; 66 // this needs to be investigated, but for now let's just filter such situations out 67 var reg = cpu.GetRegisters().FirstOrDefault(x => x.Aliases != null && x.Aliases.Contains(register)); 68 // `reg` is a struct, so it'll never be `null` 69 if(reg.Aliases == null) 70 { 71 throw new RecoverableException($"Wrong register name: {register}"); 72 } 73 return cpu.GetRegister(reg.Index); 74 } 75 GetRegistersValues(this ICPUWithRegisters cpu)76 public static string[,] GetRegistersValues(this ICPUWithRegisters cpu) 77 { 78 var result = new List<Tuple<string, int, ulong>>(); 79 80 foreach(var reg in cpu.GetRegisters()/*.Where(r => r.Aliases != null)*/) 81 { 82 result.Add(Tuple.Create(reg.ToString(), reg.Index, cpu.GetRegister(reg.Index).RawValue)); 83 } 84 85 var table = new Table().AddRow(" Name ", " Index ", " Value "); 86 table.AddRows(result, x => " {0} ".FormatWith(x.Item1), x => " {0} ".FormatWith(x.Item2), x => " 0x{0:X} ".FormatWith(x.Item3)); 87 return table.ToArray(); 88 } 89 } 90 } 91 92