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