1 //
2 // Copyright (c) 2010-2023 Antmicro
3 // Copyright (c) 2011-2015 Realtime Embedded
4 //
5 // This file is licensed under the MIT License.
6 // Full license text is available in 'licenses/MIT.txt'.
7 //
8 using System;
9 using System.Reflection;
10 using System.Linq;
11 using System.Collections.Generic;
12 using Antmicro.Renode.Utilities;
13 
14 namespace Antmicro.Renode.Peripherals.Bus.Wrappers
15 {
16     public class RegisterMapper
17     {
RegisterMapper(Type peripheralType)18         public RegisterMapper(Type peripheralType)
19         {
20             var types = peripheralType.GetAllNestedTypes();
21             var interestingEnums = new List<Type>();
22 
23             var enumsWithAttribute = types.Where(t => t.GetCustomAttributes(false).Any(x => x is RegistersDescriptionAttribute));
24             if (enumsWithAttribute != null)
25             {
26                 interestingEnums.AddRange(enumsWithAttribute);
27             }
28             interestingEnums.AddRange(types.Where(t => t.BaseType == typeof(Enum) && t.Name.IndexOf("register", StringComparison.CurrentCultureIgnoreCase) != -1));
29 
30             foreach (var type in interestingEnums)
31             {
32                 foreach (var value in type.GetEnumValues())
33                 {
34                     var l = Convert.ToInt64(value);
35                     var s = Enum.GetName(type, value);
36 
37                     if (!map.ContainsKey(l))
38                     {
39                         map.Add(l, s);
40                     }
41                 }
42             }
43         }
44 
ToString(long offset, string format)45         public string ToString(long offset, string format)
46         {
47             string name;
48             if (!map.ContainsKey(offset))
49             {
50                 var closestCandidates = map.Keys.Where(k => k < offset).ToList();
51                 if (closestCandidates.Count > 0)
52                 {
53                     var closest = closestCandidates.Max();
54                     name = string.Format("{0}+0x{1:x}", map[closest], offset - closest);
55                 }
56                 else
57                 {
58                     name = "unknown";
59                 }
60             }
61             else
62             {
63                 name = map[offset];
64             }
65 
66             return string.Format(format, name);
67         }
68 
69         private readonly Dictionary<long, string> map = new Dictionary<long, string>();
70 
71         [AttributeUsage(AttributeTargets.Enum)]
72         public class RegistersDescriptionAttribute : Attribute { }
73     }
74 }
75 
76