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 using System;
8 using System.Linq;
9 using System.Text;
10 
11 namespace Antmicro.Renode.Utilities.GDB.Commands
12 {
13     internal class ReadRegisterCommand : Command
14     {
ReadRegisterCommand(CommandsManager manager)15         public ReadRegisterCommand(CommandsManager manager) : base(manager)
16         {
17         }
18 
19         [Execute("p")]
Execute( [Argument(Encoding = ArgumentAttribute.ArgumentEncoding.HexNumber)]int registerNumber)20         public PacketData Execute(
21             [Argument(Encoding = ArgumentAttribute.ArgumentEncoding.HexNumber)]int registerNumber)
22         {
23             var content = new StringBuilder();
24 
25             // if register exists in emulated core return current value of this
26             if(manager.Cpu.GetRegisters().Any(x => x.Index == registerNumber))
27             {
28                 foreach(var b in manager.Cpu.GetRegister(registerNumber).GetBytes(manager.Cpu.Endianness))
29                 {
30                     content.AppendFormat("{0:x2}", b);
31                 }
32             }
33             else
34             {
35                 // if register does not exist in emulated core but is defined in a feature
36                 // return a zero value with number of bytes defined in the feature
37                 var selectedRegisters = manager.Cpu.GDBFeatures.SelectMany(f => f.Registers)
38                     .Where(r => r.Number == registerNumber);
39 
40                 if(selectedRegisters.Any())
41                 {
42                     for(var b = 0; b < selectedRegisters.First().Size / 8; b++)
43                     {
44                         content.AppendFormat("00");
45                     }
46                 }
47             }
48 
49             ExpandRegisterValue(ref content, 0, content.Length, registerNumber);
50             if(content.Length > 0)
51             {
52                 return new PacketData(content.ToString());
53             }
54 
55             // else return error
56             return PacketData.ErrorReply(Error.OperationNotPermitted);
57 
58         }
59     }
60 }
61 
62