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