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 Antmicro.Renode.Peripherals.Bus;
9 using Antmicro.Renode.Core.Structure.Registers;
10 using System.Collections.Generic;
11 using System;
12 using Antmicro.Renode.Core;
13 using Antmicro.Renode.Logging;
14 
15 namespace Antmicro.Renode.Peripherals
16 {
17     public abstract class BasicDoubleWordPeripheral : IDoubleWordPeripheral, IProvidesRegisterCollection<DoubleWordRegisterCollection>
18     {
BasicDoubleWordPeripheral(IMachine machine)19         public BasicDoubleWordPeripheral(IMachine machine)
20         {
21             this.machine = machine;
22             sysbus = machine.GetSystemBus(this);
23             RegistersCollection = new DoubleWordRegisterCollection(this);
24         }
25 
Reset()26         public virtual void Reset()
27         {
28             RegistersCollection.Reset();
29         }
30 
ReadDoubleWord(long offset)31         public virtual uint ReadDoubleWord(long offset)
32         {
33             return RegistersCollection.Read(offset);
34         }
35 
WriteDoubleWord(long offset, uint value)36         public virtual void WriteDoubleWord(long offset, uint value)
37         {
38             RegistersCollection.Write(offset, value);
39         }
40 
41         public DoubleWordRegisterCollection RegistersCollection { get; private set; }
42 
43         protected readonly IMachine machine;
44         protected readonly IBusController sysbus;
45     }
46 
47     public static class BasicDoubleWordPeripheralExtensions
48     {
Tag32(this System.Enum o, IProvidesRegisterCollection<DoubleWordRegisterCollection> p, uint resetValue = 0, string name = R)49         public static void Tag32(this System.Enum o, IProvidesRegisterCollection<DoubleWordRegisterCollection> p, uint resetValue = 0, string name = "")
50         {
51         }
52 
Define32Many(this System.Enum o, IProvidesRegisterCollection<DoubleWordRegisterCollection> p, uint count, Action<DoubleWordRegister, int> setup, uint stepInBytes = 4, uint resetValue = 0, bool softResettable = true, string name = R)53         public static void Define32Many(this System.Enum o, IProvidesRegisterCollection<DoubleWordRegisterCollection> p, uint count, Action<DoubleWordRegister, int> setup, uint stepInBytes = 4, uint resetValue = 0, bool softResettable = true, string name = "")
54         {
55             DefineMany(o, p, count, setup, stepInBytes, resetValue, softResettable, name);
56         }
57 
DefineMany(this System.Enum o, DoubleWordRegisterCollection c, uint count, Action<DoubleWordRegister, int> setup, uint stepInBytes = 4, uint resetValue = 0, bool softResettable = true, string name = R)58         public static void DefineMany(this System.Enum o, DoubleWordRegisterCollection c, uint count, Action<DoubleWordRegister, int> setup, uint stepInBytes = 4, uint resetValue = 0, bool softResettable = true, string name = "")
59         {
60             var baseAddress = Convert.ToInt64(o);
61             for(var i = 0; i < count; i++)
62             {
63                 var register = c.DefineRegister(baseAddress + i * stepInBytes, resetValue, softResettable);
64                 setup(register, i);
65             }
66         }
67 
DefineMany(this System.Enum o, IProvidesRegisterCollection<DoubleWordRegisterCollection> p, uint count, Action<DoubleWordRegister, int> setup, uint stepInBytes = 4, uint resetValue = 0, bool softResettable = true, string name = R)68         public static void DefineMany(this System.Enum o, IProvidesRegisterCollection<DoubleWordRegisterCollection> p, uint count, Action<DoubleWordRegister, int> setup, uint stepInBytes = 4, uint resetValue = 0, bool softResettable = true, string name = "")
69         {
70             DefineMany(o, p.RegistersCollection, count, setup, stepInBytes, resetValue, softResettable, name);
71         }
72 
73         // this method it for easier use in peripherals implementing registers of different width
Define32(this System.Enum o, IProvidesRegisterCollection<DoubleWordRegisterCollection> p, uint resetValue = 0, bool softResettable = true, string name = R)74         public static DoubleWordRegister Define32(this System.Enum o, IProvidesRegisterCollection<DoubleWordRegisterCollection> p, uint resetValue = 0, bool softResettable = true, string name = "")
75         {
76             return Define(o, p, resetValue, softResettable, name);
77         }
78 
Define(this System.Enum o, DoubleWordRegisterCollection c, uint resetValue = 0, bool softResettable = true, string name = R)79         public static DoubleWordRegister Define(this System.Enum o, DoubleWordRegisterCollection c, uint resetValue = 0, bool softResettable = true, string name = "")
80         {
81             return c.DefineRegister(Convert.ToInt64(o), resetValue, softResettable);
82         }
83 
Define(this System.Enum o, IProvidesRegisterCollection<DoubleWordRegisterCollection> p, uint resetValue = 0, bool softResettable = true, string name = R)84         public static DoubleWordRegister Define(this System.Enum o, IProvidesRegisterCollection<DoubleWordRegisterCollection> p, uint resetValue = 0, bool softResettable = true, string name = "")
85         {
86             return Define(o, p.RegistersCollection, resetValue, softResettable, name);
87         }
88 
DefineConditional(this System.Enum o, DoubleWordRegisterCollection c, Func<bool> condition, ushort resetValue = 0, bool softResettable = true, string name = R)89         public static DoubleWordRegister DefineConditional(this System.Enum o, DoubleWordRegisterCollection c, Func<bool> condition, ushort resetValue = 0, bool softResettable = true, string name = "")
90         {
91             return c.DefineConditionalRegister(Convert.ToInt64(o), condition, resetValue, softResettable);
92         }
93 
DefineConditional(this System.Enum o, IProvidesRegisterCollection<DoubleWordRegisterCollection> p, Func<bool> condition, ushort resetValue = 0, bool softResettable = true, string name = R)94         public static DoubleWordRegister DefineConditional(this System.Enum o, IProvidesRegisterCollection<DoubleWordRegisterCollection> p, Func<bool> condition, ushort resetValue = 0, bool softResettable = true, string name = "")
95         {
96             return o.DefineConditional(p.RegistersCollection, condition, resetValue, softResettable);
97         }
98 
DefineManyConditional(this System.Enum o, DoubleWordRegisterCollection c, uint count, Func<int, bool> condition, Action<DoubleWordRegister, int> setup, uint stepInBytes = 1, uint resetValue = 0, string name = R)99         public static void DefineManyConditional(this System.Enum o, DoubleWordRegisterCollection c, uint count, Func<int, bool> condition, Action<DoubleWordRegister, int> setup, uint stepInBytes = 1, uint resetValue = 0, string name = "")
100         {
101             var baseAddress = Convert.ToInt64(o);
102             for(var i = 0; i < count; i++)
103             {
104                 var idx = i;
105                 var register = c.DefineConditionalRegister(baseAddress + i * stepInBytes, () => condition(idx), resetValue);
106                 setup(register, i);
107             }
108         }
109 
DefineManyConditional(this System.Enum o, IProvidesRegisterCollection<DoubleWordRegisterCollection> p, uint count, Func<int, bool> condition, Action<DoubleWordRegister, int> setup, uint stepInBytes = 1, uint resetValue = 0, string name = R)110         public static void DefineManyConditional(this System.Enum o, IProvidesRegisterCollection<DoubleWordRegisterCollection> p, uint count, Func<int, bool> condition, Action<DoubleWordRegister, int> setup, uint stepInBytes = 1, uint resetValue = 0, string name = "")
111         {
112             o.DefineManyConditional(p.RegistersCollection, count, condition, setup, stepInBytes, resetValue, name);
113         }
114 
DefineManyConditional(this System.Enum o, DoubleWordRegisterCollection c, uint count, Func<bool> condition, Action<DoubleWordRegister, int> setup, uint stepInBytes = 1, uint resetValue = 0, string name = R)115         public static void DefineManyConditional(this System.Enum o, DoubleWordRegisterCollection c, uint count, Func<bool> condition, Action<DoubleWordRegister, int> setup, uint stepInBytes = 1, uint resetValue = 0, string name = "")
116         {
117             o.DefineManyConditional(c, count, _ => condition(), setup, stepInBytes, resetValue, name);
118         }
119 
DefineManyConditional(this System.Enum o, IProvidesRegisterCollection<DoubleWordRegisterCollection> p, uint count, Func<bool> condition, Action<DoubleWordRegister, int> setup, uint stepInBytes = 1, uint resetValue = 0, string name = R)120         public static void DefineManyConditional(this System.Enum o, IProvidesRegisterCollection<DoubleWordRegisterCollection> p, uint count, Func<bool> condition, Action<DoubleWordRegister, int> setup, uint stepInBytes = 1, uint resetValue = 0, string name = "")
121         {
122             o.DefineManyConditional(p.RegistersCollection, count, _ => condition(), setup, stepInBytes, resetValue, name);
123         }
124 
Bind(this System.Enum o, IProvidesRegisterCollection<DoubleWordRegisterCollection> p, DoubleWordRegister reg)125         public static DoubleWordRegister Bind(this System.Enum o, IProvidesRegisterCollection<DoubleWordRegisterCollection> p, DoubleWordRegister reg)
126         {
127             return p.RegistersCollection.AddRegister(Convert.ToInt64(o), reg);
128         }
129 
BindMany(this System.Enum o, IProvidesRegisterCollection<DoubleWordRegisterCollection> p, uint count, Func<int, DoubleWordRegister> setup, uint stepInBytes = 4)130         public static void BindMany(this System.Enum o, IProvidesRegisterCollection<DoubleWordRegisterCollection> p, uint count, Func<int, DoubleWordRegister> setup, uint stepInBytes = 4)
131         {
132             var baseAddress = Convert.ToInt64(o);
133             for(var i = 0; i < count; i++)
134             {
135                 var register = setup(i);
136                 p.RegistersCollection.AddRegister(baseAddress + i * stepInBytes, register);
137             }
138         }
139     }
140 }
141