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 Antmicro.Renode.Core;
8 using ELFSharp.ELF;
9 using Antmicro.Renode.Utilities;
10 using Antmicro.Renode.Logging;
11 using Antmicro.Renode.Peripherals.Timers;
12 
13 namespace Antmicro.Renode.Peripherals.CPU
14 {
15     public partial class Minerva : RiscV32
16     {
Minerva(IMachine machine, uint hartId = 0, IRiscVTimeProvider timeProvider = null)17         public Minerva(IMachine machine, uint hartId = 0, IRiscVTimeProvider timeProvider = null) : base(machine, "rv32i", timeProvider, hartId, PrivilegedArchitecture.Priv1_09, Endianess.LittleEndian)
18         {
19             CSRValidation = CSRValidationLevel.None;
20 
21             RegisterCSR((ulong)CSRs.IrqMask, () => (ulong)irqMask, value =>
22             {
23                 lock(locker)
24                 {
25                     irqMask = (uint)value;
26                     this.Log(LogLevel.Noisy, "IRQ mask set to 0x{0:X}", irqMask);
27                     Update();
28                 }
29             });
30             RegisterCSR((ulong)CSRs.IrqPending, () => (ulong)irqPending, value =>
31             {
32                 lock(locker)
33                 {
34                     irqPending = (uint)value;
35                     this.Log(LogLevel.Noisy, "IRQ pending set to 0x{0:X}", irqPending);
36                     Update();
37                 }
38             });
39         }
40 
OnGPIO(int number, bool value)41         public override void OnGPIO(int number, bool value)
42         {
43             lock(locker)
44             {
45                 this.Log(LogLevel.Noisy, "GPIO #{0} set to: {1}", number, value);
46                 BitHelper.SetBit(ref irqPending, (byte)number, value);
47                 Update();
48             }
49         }
50 
Update()51         private void Update()
52         {
53             //We support only Machine mode, with external interrupts. An additional interrupt controller would be required to have more advanced handling.
54             base.OnGPIO((int)IrqType.MachineExternalInterrupt, (irqPending & irqMask) != 0);
55         }
56 
57         private uint irqMask;
58         private uint irqPending;
59 
60         private readonly object locker = new object();
61 
62         private enum CSRs
63         {
64             IrqMask = 0x330,
65             IrqPending = 0x360,
66         }
67     }
68 }
69