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