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 using System; 8 using Antmicro.Renode.Core; 9 using Antmicro.Renode.Core.Structure; 10 using Antmicro.Renode.Exceptions; 11 using Antmicro.Renode.Peripherals.CPU; 12 13 namespace Antmicro.Renode.Peripherals.Bus 14 { 15 public abstract class BusRegistration : IBusRegistration, IConditionalRegistration 16 { BusRegistration(ulong startingPoint, ulong offset = 0, IPeripheral cpu = null, ICluster<ICPU> cluster = null, StateMask? stateMask = null, string condition = null)17 protected BusRegistration(ulong startingPoint, ulong offset = 0, IPeripheral cpu = null, ICluster<ICPU> cluster = null, StateMask? stateMask = null, string condition = null) 18 { 19 if(cpu != null && cluster != null) 20 { 21 throw new ConstructionException("CPU and cluster cannot be specified at the same time"); 22 } 23 24 if(stateMask != null && condition != null) 25 { 26 throw new ConstructionException("State mask and condition cannot be specified at the same time"); 27 } 28 29 Initiator = cpu; 30 Cluster = cluster; 31 StateMask = stateMask; 32 Condition = condition; 33 Offset = offset; 34 StartingPoint = startingPoint; 35 } 36 37 public IPeripheral Initiator { get; } 38 public ICluster<ICPU> Cluster { get; } 39 public StateMask? StateMask { get; } 40 public string Condition { get; } 41 public ulong Offset { get; set; } 42 public ulong StartingPoint { get; set; } 43 44 public virtual string PrettyString 45 { 46 get 47 { 48 return ToString(); 49 } 50 } 51 Equals(object obj)52 public override bool Equals(object obj) 53 { 54 var other = obj as BusRegistration; 55 if(other == null) 56 return false; 57 if(ReferenceEquals(this, obj)) 58 return true; 59 60 return StartingPoint == other.StartingPoint && Offset == other.Offset && Initiator == other.Initiator && Cluster == other.Cluster 61 && StateMask.Equals(other.StateMask) && Condition == other.Condition; 62 } 63 GetHashCode()64 public override int GetHashCode() 65 { 66 return 17 * StartingPoint.GetHashCode() + 23 * Offset.GetHashCode() + 101 * (Initiator?.GetHashCode() ?? 0) + 397 * (Cluster?.GetHashCode() ?? 0) 67 + 401 * (StateMask?.GetHashCode() ?? 0) + 409 * (Condition?.GetHashCode() ?? 0); 68 } 69 WithInitiatorAndStateMask(IPeripheral initiator, StateMask mask)70 public abstract IConditionalRegistration WithInitiatorAndStateMask(IPeripheral initiator, StateMask mask); 71 72 protected void RegisterForEachContextInner<T>(Action<T> register, Func<ICPU, T> registrationForCpuGetter) 73 where T : BusRegistration 74 { 75 if(Cluster != null) 76 { 77 foreach(var cpu in Cluster.Clustered) 78 { 79 register(registrationForCpuGetter(cpu)); 80 } 81 } 82 else 83 { 84 register((T)this); 85 } 86 } 87 } 88 } 89