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 BasicWordPeripheral : IWordPeripheral, IProvidesRegisterCollection<WordRegisterCollection>
18     {
BasicWordPeripheral(IMachine machine)19         public BasicWordPeripheral(IMachine machine)
20         {
21             this.machine = machine;
22             sysbus = machine.GetSystemBus(this);
23             RegistersCollection = new WordRegisterCollection(this);
24         }
25 
Reset()26         public virtual void Reset()
27         {
28             RegistersCollection.Reset();
29         }
30 
ReadWord(long offset)31         public virtual ushort ReadWord(long offset)
32         {
33             return RegistersCollection.Read(offset);
34         }
35 
WriteWord(long offset, ushort value)36         public virtual void WriteWord(long offset, ushort value)
37         {
38             RegistersCollection.Write(offset, value);
39         }
40 
41         public WordRegisterCollection RegistersCollection { get; private set; }
42 
43         protected readonly IMachine machine;
44         protected readonly IBusController sysbus;
45     }
46 
47     public static class BasicWordPeripheralExtensions
48     {
Tag16(this System.Enum o, IProvidesRegisterCollection<WordRegisterCollection> p, ushort resetValue = 0, string name = R)49         public static void Tag16(this System.Enum o, IProvidesRegisterCollection<WordRegisterCollection> p, ushort resetValue = 0, string name = "")
50         {
51         }
52 
Define16Many(this System.Enum o, IProvidesRegisterCollection<WordRegisterCollection> p, uint count, Action<WordRegister, int> setup, uint stepInBytes = 2, ushort resetValue = 0, bool softResettable = true, string name = R)53         public static void Define16Many(this System.Enum o, IProvidesRegisterCollection<WordRegisterCollection> p, uint count, Action<WordRegister, int> setup, uint stepInBytes = 2, ushort 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, WordRegisterCollection c, uint count, Action<WordRegister, int> setup, uint stepInBytes = 2, ushort resetValue = 0, bool softResettable = true, string name = R)58         public static void DefineMany(this System.Enum o, WordRegisterCollection c, uint count, Action<WordRegister, int> setup, uint stepInBytes = 2, ushort 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<WordRegisterCollection> p, uint count, Action<WordRegister, int> setup, uint stepInBytes = 2, ushort resetValue = 0, bool softResettable = true, string name = R)68         public static void DefineMany(this System.Enum o, IProvidesRegisterCollection<WordRegisterCollection> p, uint count, Action<WordRegister, int> setup, uint stepInBytes = 2, ushort resetValue = 0, bool softResettable = true, string name = "")
69         {
70             o.DefineMany(p.RegistersCollection, count, setup, stepInBytes, resetValue, softResettable, name);
71         }
72 
Define16(this System.Enum o, IProvidesRegisterCollection<WordRegisterCollection> p, ushort resetValue = 0, bool softResettable = true, string name = R)73         public static WordRegister Define16(this System.Enum o, IProvidesRegisterCollection<WordRegisterCollection> p, ushort resetValue = 0, bool softResettable = true, string name = "")
74         {
75             return Define(o, p, resetValue, softResettable);
76         }
77 
Define(this System.Enum o, WordRegisterCollection c, ushort resetValue = 0, bool softResettable = true, string name = R)78         public static WordRegister Define(this System.Enum o, WordRegisterCollection c, ushort resetValue = 0, bool softResettable = true, string name = "")
79         {
80             return c.DefineRegister(Convert.ToInt64(o), resetValue, softResettable);
81         }
82 
Define(this System.Enum o, IProvidesRegisterCollection<WordRegisterCollection> p, ushort resetValue = 0, bool softResettable = true, string name = R)83         public static WordRegister Define(this System.Enum o, IProvidesRegisterCollection<WordRegisterCollection> p, ushort resetValue = 0, bool softResettable = true, string name = "")
84         {
85             return p.RegistersCollection.DefineRegister(Convert.ToInt64(o), resetValue, softResettable);
86         }
87 
DefineConditional(this System.Enum o, WordRegisterCollection c, Func<bool> condition, ushort resetValue = 0, bool softResettable = true, string name = R)88         public static WordRegister DefineConditional(this System.Enum o, WordRegisterCollection c, Func<bool> condition, ushort resetValue = 0, bool softResettable = true, string name = "")
89         {
90             return c.DefineConditionalRegister(Convert.ToInt64(o), condition, resetValue, softResettable);
91         }
92 
DefineConditional(this System.Enum o, IProvidesRegisterCollection<WordRegisterCollection> p, Func<bool> condition, ushort resetValue = 0, bool softResettable = true, string name = R)93         public static WordRegister DefineConditional(this System.Enum o, IProvidesRegisterCollection<WordRegisterCollection> p, Func<bool> condition, ushort resetValue = 0, bool softResettable = true, string name = "")
94         {
95             return o.DefineConditional(p.RegistersCollection, condition, resetValue, softResettable);
96         }
97 
DefineManyConditional(this System.Enum o, WordRegisterCollection c, uint count, Func<int, bool> condition, Action<WordRegister, int> setup, uint stepInBytes = 1, ushort resetValue = 0, string name = R)98         public static void DefineManyConditional(this System.Enum o, WordRegisterCollection c, uint count, Func<int, bool> condition, Action<WordRegister, int> setup, uint stepInBytes = 1, ushort resetValue = 0, string name = "")
99         {
100             var baseAddress = Convert.ToInt64(o);
101             for(var i = 0; i < count; i++)
102             {
103                 var idx = i;
104                 var register = c.DefineConditionalRegister(baseAddress + i * stepInBytes, () => condition(idx), resetValue);
105                 setup(register, i);
106             }
107         }
108 
DefineManyConditional(this System.Enum o, IProvidesRegisterCollection<WordRegisterCollection> p, uint count, Func<int, bool> condition, Action<WordRegister, int> setup, uint stepInBytes = 1, ushort resetValue = 0, string name = R)109         public static void DefineManyConditional(this System.Enum o, IProvidesRegisterCollection<WordRegisterCollection> p, uint count, Func<int, bool> condition, Action<WordRegister, int> setup, uint stepInBytes = 1, ushort resetValue = 0, string name = "")
110         {
111             o.DefineManyConditional(p.RegistersCollection, count, condition, setup, stepInBytes, resetValue, name);
112         }
113 
DefineManyConditional(this System.Enum o, WordRegisterCollection c, uint count, Func<bool> condition, Action<WordRegister, int> setup, uint stepInBytes = 1, ushort resetValue = 0, string name = R)114         public static void DefineManyConditional(this System.Enum o, WordRegisterCollection c, uint count, Func<bool> condition, Action<WordRegister, int> setup, uint stepInBytes = 1, ushort resetValue = 0, string name = "")
115         {
116             o.DefineManyConditional(c, count, _ => condition(), setup, stepInBytes, resetValue, name);
117         }
118 
DefineManyConditional(this System.Enum o, IProvidesRegisterCollection<WordRegisterCollection> p, uint count, Func<bool> condition, Action<WordRegister, int> setup, uint stepInBytes = 1, ushort resetValue = 0, string name = R)119         public static void DefineManyConditional(this System.Enum o, IProvidesRegisterCollection<WordRegisterCollection> p, uint count, Func<bool> condition, Action<WordRegister, int> setup, uint stepInBytes = 1, ushort resetValue = 0, string name = "")
120         {
121             o.DefineManyConditional(p.RegistersCollection, count, _ => condition(), setup, stepInBytes, resetValue, name);
122         }
123 
Bind(this System.Enum o, IProvidesRegisterCollection<WordRegisterCollection> p, WordRegister reg, string name = R)124         public static WordRegister Bind(this System.Enum o, IProvidesRegisterCollection<WordRegisterCollection> p, WordRegister reg, string name = "")
125         {
126             return p.RegistersCollection.AddRegister(Convert.ToInt64(o), reg);
127         }
128 
BindMany(this System.Enum o, IProvidesRegisterCollection<WordRegisterCollection> p, uint count, Func<int, WordRegister> setup, uint stepInBytes = 4)129         public static void BindMany(this System.Enum o, IProvidesRegisterCollection<WordRegisterCollection> p, uint count, Func<int, WordRegister> setup, uint stepInBytes = 4)
130         {
131             var baseAddress = Convert.ToInt64(o);
132             for(var i = 0; i < count; i++)
133             {
134                 var register = setup(i);
135                 p.RegistersCollection.AddRegister(baseAddress + i * stepInBytes, register);
136             }
137         }
138     }
139 }
140