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.Reflection;
10 using System.Collections.Generic;
11 using System.Runtime.ExceptionServices;
12 using ELFSharp.ELF;
13 using Antmicro.Renode.Logging;
14 using Antmicro.Renode.Utilities;
15 using Antmicro.Renode.Exceptions;
16 using Antmicro.Renode.Peripherals.CPU;
17 using Antmicro.Renode.Peripherals.CPU.Registers;
18 using Machine = Antmicro.Renode.Core.Machine;
19 
20 namespace Antmicro.Renode.Peripherals.CoSimulated
21 {
22     public partial class CoSimulatedRiscV32 : CoSimulatedCPU, ICpuSupportingGdb
23     {
CoSimulatedRiscV32(string cpuType, Machine machine, Endianess endianness = Endianess.LittleEndian, CpuBitness bitness = CpuBitness.Bits32, string simulationFilePathLinux = null, string simulationFilePathWindows = null, string simulationFilePathMacOS = null, string address = null)24         public CoSimulatedRiscV32(string cpuType, Machine machine, Endianess endianness = Endianess.LittleEndian,
25         CpuBitness bitness = CpuBitness.Bits32, string simulationFilePathLinux = null,
26         string simulationFilePathWindows = null, string simulationFilePathMacOS = null, string address = null)
27             : base(cpuType, machine, endianness, bitness, simulationFilePathLinux, simulationFilePathWindows, simulationFilePathMacOS, address)
28         {
29         }
30 
31         public override string Architecture { get { return "riscv"; } }
32 
33         public string GDBArchitecture { get { return "riscv:rv32"; } }
34 
35         public List<GDBFeatureDescriptor> GDBFeatures { get { return new List<GDBFeatureDescriptor>(); } }
36 
SetRegister(int register, RegisterValue value)37         public void SetRegister(int register, RegisterValue value)
38         {
39             if(!mapping.TryGetValue((CoSimulatedRiscV32Registers)register, out var r))
40             {
41                 throw new RecoverableException($"Wrong register index: {register}");
42             }
43             if(r.IsReadonly)
44             {
45                 throw new RecoverableException($"Register: {register} value is not writable.");
46             }
47 
48             SetRegisterValue32(r.Index, checked((UInt32)value));
49         }
50 
SetRegisterUnsafe(int register, RegisterValue value)51         public void SetRegisterUnsafe(int register, RegisterValue value)
52         {
53             SetRegister(register, value);
54         }
55 
GetRegister(int register)56         public RegisterValue GetRegister(int register)
57         {
58             if(!mapping.TryGetValue((CoSimulatedRiscV32Registers)register, out var r))
59             {
60                 throw new RecoverableException($"Wrong register index: {register}");
61             }
62             return GetRegisterValue32(r.Index);
63         }
64 
GetRegisterUnsafe(int register)65         public RegisterValue GetRegisterUnsafe(int register)
66         {
67             return GetRegister(register);
68         }
69 
GetRegisters()70         public IEnumerable<CPURegister> GetRegisters()
71         {
72             return mapping.Values.OrderBy(x => x.Index);
73         }
74 
EnterSingleStepModeSafely(HaltArguments args)75         public void EnterSingleStepModeSafely(HaltArguments args)
76         {
77             // this method should only be called from CPU thread,
78             // but we should check it anyway
79             CheckCpuThreadId();
80 
81             ExecutionMode = ExecutionMode.SingleStep;
82 
83             UpdateHaltedState();
84             InvokeHalted(args);
85         }
86 
AddHookAtInterruptBegin(Action<ulong> hook)87         public void AddHookAtInterruptBegin(Action<ulong> hook)
88         {
89             this.Log(LogLevel.Warning, "AddHookAtInterruptBegin not implemented");
90         }
91 
AddHookAtInterruptEnd(Action<ulong> hook)92         public void AddHookAtInterruptEnd(Action<ulong> hook)
93         {
94             this.Log(LogLevel.Warning, "AddHookAtInterruptEnd not implemented");
95         }
96 
AddHook(ulong addr, Action<ICpuSupportingGdb, ulong> hook)97         public void AddHook(ulong addr, Action<ICpuSupportingGdb, ulong> hook)
98         {
99             this.Log(LogLevel.Warning, "AddHook not implemented");
100         }
101 
RemoveHook(ulong addr, Action<ICpuSupportingGdb, ulong> hook)102         public void RemoveHook(ulong addr, Action<ICpuSupportingGdb, ulong> hook)
103         {
104             this.Log(LogLevel.Warning, "RemoveHook not implemented");
105         }
106 
AddHookAtWfiStateChange(Action<bool> hook)107         public void AddHookAtWfiStateChange(Action<bool> hook)
108         {
109             this.Log(LogLevel.Warning, "AddHookAtWfiStateChange not implemented");
110         }
111 
RemoveHooksAt(ulong addr)112         public void RemoveHooksAt(ulong addr)
113         {
114             this.Log(LogLevel.Warning, "RemoveHooksAt not implemented");
115         }
116 
RemoveAllHooks()117         public void RemoveAllHooks()
118         {
119             this.Log(LogLevel.Warning, "RemoveAllHooks not implemented");
120         }
121     }
122 }
123