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