1 // 2 // Copyright (c) 2010-2025 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 System; 9 using System.Collections.Generic; 10 using Antmicro.Renode.Core; 11 using Antmicro.Renode.Core.Structure; 12 using Antmicro.Renode.Utilities; 13 using Antmicro.Renode.Peripherals.CPU; 14 using Antmicro.Renode.Peripherals.Memory; 15 using ELFSharp.ELF; 16 17 using Range = Antmicro.Renode.Core.Range; 18 19 namespace Antmicro.Renode.Peripherals.Bus 20 { 21 public abstract class BusControllerProxy : IBusController 22 { Reset()23 public void Reset() 24 { 25 ParentController.Reset(); 26 } 27 BusControllerProxy(IBusController parentController)28 public BusControllerProxy(IBusController parentController) 29 { 30 ParentController = parentController; 31 } 32 ReadByte(ulong address, IPeripheral context = null, ulong? cpuState = null)33 public virtual byte ReadByte(ulong address, IPeripheral context = null, ulong? cpuState = null) 34 { 35 if(ValidateOperation(ref address, BusAccessPrivileges.Read, context)) 36 { 37 return ParentController.ReadByte(address, context, cpuState); 38 } 39 return (byte)0; 40 } 41 ReadByteWithState(ulong address, IPeripheral context, IContextState stateObj)42 public virtual byte ReadByteWithState(ulong address, IPeripheral context, IContextState stateObj) 43 { 44 if(ValidateOperation(ref address, BusAccessPrivileges.Read, context)) 45 { 46 return ParentController.ReadByteWithState(address, context, stateObj); 47 } 48 return (byte)0; 49 } 50 WriteByte(ulong address, byte value, IPeripheral context = null, ulong? cpuState = null)51 public virtual void WriteByte(ulong address, byte value, IPeripheral context = null, ulong? cpuState = null) 52 { 53 if(ValidateOperation(ref address, BusAccessPrivileges.Write, context)) 54 { 55 ParentController.WriteByte(address, value, context, cpuState); 56 } 57 } 58 WriteByteWithState(ulong address, byte value, IPeripheral context, IContextState stateObj)59 public virtual void WriteByteWithState(ulong address, byte value, IPeripheral context, IContextState stateObj) 60 { 61 if(ValidateOperation(ref address, BusAccessPrivileges.Write, context)) 62 { 63 ParentController.WriteByteWithState(address, value, context, stateObj); 64 } 65 } 66 ReadWord(ulong address, IPeripheral context = null, ulong? cpuState = null)67 public virtual ushort ReadWord(ulong address, IPeripheral context = null, ulong? cpuState = null) 68 { 69 if(ValidateOperation(ref address, BusAccessPrivileges.Read, context)) 70 { 71 return ParentController.ReadWord(address, context, cpuState); 72 } 73 return (ushort)0; 74 } 75 ReadWordWithState(ulong address, IPeripheral context, IContextState stateObj)76 public virtual ushort ReadWordWithState(ulong address, IPeripheral context, IContextState stateObj) 77 { 78 if(ValidateOperation(ref address, BusAccessPrivileges.Read, context)) 79 { 80 return ParentController.ReadWordWithState(address, context, stateObj); 81 } 82 return (ushort)0; 83 } 84 WriteWord(ulong address, ushort value, IPeripheral context = null, ulong? cpuState = null)85 public virtual void WriteWord(ulong address, ushort value, IPeripheral context = null, ulong? cpuState = null) 86 { 87 if(ValidateOperation(ref address, BusAccessPrivileges.Write, context)) 88 { 89 ParentController.WriteWord(address, value, context, cpuState); 90 } 91 } 92 WriteWordWithState(ulong address, ushort value, IPeripheral context, IContextState stateObj)93 public virtual void WriteWordWithState(ulong address, ushort value, IPeripheral context, IContextState stateObj) 94 { 95 if(ValidateOperation(ref address, BusAccessPrivileges.Write, context)) 96 { 97 ParentController.WriteWordWithState(address, value, context, stateObj); 98 } 99 } 100 ReadDoubleWord(ulong address, IPeripheral context = null, ulong? cpuState = null)101 public virtual uint ReadDoubleWord(ulong address, IPeripheral context = null, ulong? cpuState = null) 102 { 103 if(ValidateOperation(ref address, BusAccessPrivileges.Read, context)) 104 { 105 return ParentController.ReadDoubleWord(address, context, cpuState); 106 } 107 return (uint)0; 108 } 109 ReadDoubleWordWithState(ulong address, IPeripheral context, IContextState stateObj)110 public virtual uint ReadDoubleWordWithState(ulong address, IPeripheral context, IContextState stateObj) 111 { 112 if(ValidateOperation(ref address, BusAccessPrivileges.Read, context)) // todo state 113 { 114 return ParentController.ReadDoubleWordWithState(address, context, stateObj); 115 } 116 return (uint)0; 117 } 118 WriteDoubleWord(ulong address, uint value, IPeripheral context = null, ulong? cpuState = null)119 public virtual void WriteDoubleWord(ulong address, uint value, IPeripheral context = null, ulong? cpuState = null) 120 { 121 if(ValidateOperation(ref address, BusAccessPrivileges.Write, context)) 122 { 123 ParentController.WriteDoubleWord(address, value, context, cpuState); 124 } 125 } 126 WriteDoubleWordWithState(ulong address, uint value, IPeripheral context, IContextState stateObj)127 public virtual void WriteDoubleWordWithState(ulong address, uint value, IPeripheral context, IContextState stateObj) 128 { 129 if(ValidateOperation(ref address, BusAccessPrivileges.Write, context)) 130 { 131 ParentController.WriteDoubleWordWithState(address, value, context, stateObj); 132 } 133 } 134 ReadBytes(ulong address, int count, byte[] destination, int startIndex, bool onlyMemory = false, IPeripheral context = null)135 public virtual void ReadBytes(ulong address, int count, byte[] destination, int startIndex, bool onlyMemory = false, IPeripheral context = null) 136 { 137 if(ValidateOperation(ref address, BusAccessPrivileges.Read, context)) 138 { 139 ParentController.ReadBytes(address, count, destination, startIndex, onlyMemory, context); 140 } 141 } 142 ReadBytes(ulong address, int count, bool onlyMemory = false, IPeripheral context = null)143 public virtual byte[] ReadBytes(ulong address, int count, bool onlyMemory = false, IPeripheral context = null) 144 { 145 var result = new byte[count]; 146 ReadBytes(address, count, result, 0, onlyMemory, context); 147 return result; 148 } 149 ReadBytes(long offset, int count, IPeripheral context = null)150 public virtual byte[] ReadBytes(long offset, int count, IPeripheral context = null) 151 { 152 return ReadBytes((ulong)offset, count, context: context); 153 } 154 WriteBytes(byte[] bytes, ulong address, bool onlyMemory = false, IPeripheral context = null)155 public virtual void WriteBytes(byte[] bytes, ulong address, bool onlyMemory = false, IPeripheral context = null) 156 { 157 WriteBytes(bytes, address, bytes.Length, onlyMemory, context); 158 } 159 WriteBytes(byte[] bytes, ulong address, int startingIndex, long count, bool onlyMemory = false, IPeripheral context = null)160 public virtual void WriteBytes(byte[] bytes, ulong address, int startingIndex, long count, bool onlyMemory = false, IPeripheral context = null) 161 { 162 if(ValidateOperation(ref address, BusAccessPrivileges.Write, context)) 163 { 164 ParentController.WriteBytes(bytes, address, startingIndex, count, onlyMemory, context); 165 } 166 } 167 WriteBytes(byte[] bytes, ulong address, long count, bool onlyMemory = false, IPeripheral context = null)168 public virtual void WriteBytes(byte[] bytes, ulong address, long count, bool onlyMemory = false, IPeripheral context = null) 169 { 170 WriteBytes(bytes, address, 0, count, onlyMemory, context); 171 } 172 WriteBytes(long offset, byte[] array, int startingIndex, int count, IPeripheral context = null)173 public virtual void WriteBytes(long offset, byte[] array, int startingIndex, int count, IPeripheral context = null) 174 { 175 WriteBytes(array, (ulong)offset, startingIndex, count, context: context); 176 } 177 TryConvertStateToUlongForContext(IPeripheral context, IContextState stateObj, out ulong? state)178 public virtual bool TryConvertStateToUlongForContext(IPeripheral context, IContextState stateObj, out ulong? state) 179 { 180 state = null; 181 if(!ParentController.TryConvertStateToUlongForContext(context, stateObj, out state)) 182 { 183 return false; 184 } 185 return true; 186 } 187 WhatIsAt(ulong address, IPeripheral context = null)188 public virtual IBusRegistered<IBusPeripheral> WhatIsAt(ulong address, IPeripheral context = null) 189 { 190 ValidateOperation(ref address, BusAccessPrivileges.Other, context); 191 return ParentController.WhatIsAt(address, context); 192 } 193 WhatPeripheralIsAt(ulong address, IPeripheral context = null)194 public virtual IPeripheral WhatPeripheralIsAt(ulong address, IPeripheral context = null) 195 { 196 ValidateOperation(ref address, BusAccessPrivileges.Other, context); 197 return ParentController.WhatPeripheralIsAt(address, context); 198 } 199 GetCPUs()200 public virtual IEnumerable<ICPU> GetCPUs() 201 { 202 return ParentController.GetCPUs(); 203 } 204 GetAllContextKeys()205 public IEnumerable<IPeripheral> GetAllContextKeys() 206 { 207 return ParentController.GetAllContextKeys(); 208 } 209 GetCPUSlot(ICPU cpu)210 public virtual int GetCPUSlot(ICPU cpu) 211 { 212 return ParentController.GetCPUSlot(cpu); 213 } 214 TryGetCurrentCPU(out ICPU cpu)215 public virtual bool TryGetCurrentCPU(out ICPU cpu) 216 { 217 return ParentController.TryGetCurrentCPU(out cpu); 218 } 219 TryGetCurrentContextState(out IPeripheralWithTransactionState context, out T stateObj)220 public virtual bool TryGetCurrentContextState<T>(out IPeripheralWithTransactionState context, out T stateObj) 221 { 222 return ParentController.TryGetCurrentContextState(out context, out stateObj); 223 } 224 GetCurrentCPU()225 public virtual ICPU GetCurrentCPU() 226 { 227 return ParentController.GetCurrentCPU(); 228 } 229 GetRegisteredPeripherals(IPeripheral context = null)230 public virtual IEnumerable<IBusRegistered<IBusPeripheral>> GetRegisteredPeripherals(IPeripheral context = null) 231 { 232 return ParentController.GetRegisteredPeripherals(context); 233 } 234 GetRegistrationsForPeripheralType(IPeripheral context = null)235 public IEnumerable<IBusRegistered<IBusPeripheral>> GetRegistrationsForPeripheralType<T>(IPeripheral context = null) 236 { 237 return ParentController.GetRegistrationsForPeripheralType<T>(context); 238 } 239 GetRegistrationPoints(IBusPeripheral peripheral)240 public virtual IEnumerable<BusRangeRegistration> GetRegistrationPoints(IBusPeripheral peripheral) 241 { 242 return ParentController.GetRegistrationPoints(peripheral); 243 } 244 DecorateWithCPUNameAndPC(string str)245 public virtual string DecorateWithCPUNameAndPC(string str) 246 { 247 return ParentController.DecorateWithCPUNameAndPC(str); 248 } 249 AddWatchpointHook(ulong address, SysbusAccessWidth width, Access access, BusHookDelegate hook)250 public virtual void AddWatchpointHook(ulong address, SysbusAccessWidth width, Access access, BusHookDelegate hook) 251 { 252 ParentController.AddWatchpointHook(address, width, access, hook); 253 } 254 SetHookAfterPeripheralRead(IBusPeripheral peripheral, Func<T, long, T> hook, Range? subrange = null)255 public virtual void SetHookAfterPeripheralRead<T>(IBusPeripheral peripheral, Func<T, long, T> hook, Range? subrange = null) 256 { 257 ParentController.SetHookAfterPeripheralRead(peripheral, hook, subrange); 258 } 259 SetHookBeforePeripheralWrite(IBusPeripheral peripheral, Func<T, long, T> hook, Range? subrange = null)260 public virtual void SetHookBeforePeripheralWrite<T>(IBusPeripheral peripheral, Func<T, long, T> hook, Range? subrange = null) 261 { 262 ParentController.SetHookBeforePeripheralWrite(peripheral, hook, subrange); 263 } 264 ClearHookAfterPeripheralRead(IBusPeripheral peripheral)265 public virtual void ClearHookAfterPeripheralRead<T>(IBusPeripheral peripheral) 266 { 267 ParentController.ClearHookAfterPeripheralRead<T>(peripheral); 268 } 269 RemoveWatchpointHook(ulong address, BusHookDelegate hook)270 public virtual void RemoveWatchpointHook(ulong address, BusHookDelegate hook) 271 { 272 ParentController.RemoveWatchpointHook(address, hook); 273 } 274 TryGetWatchpointsAt(ulong address, Access access, out List<BusHookHandler> result)275 public virtual bool TryGetWatchpointsAt(ulong address, Access access, out List<BusHookHandler> result) 276 { 277 return ParentController.TryGetWatchpointsAt(address, access, out result); 278 } 279 FindSymbolAt(ulong offset, ICPU context = null)280 public virtual string FindSymbolAt(ulong offset, ICPU context = null) 281 { 282 return ParentController.FindSymbolAt(offset, context); 283 } 284 IsAddressRangeLocked(Range range, IPeripheral context = null)285 public virtual bool IsAddressRangeLocked(Range range, IPeripheral context = null) 286 { 287 return ParentController.IsAddressRangeLocked(range, context); 288 } 289 SetAddressRangeLocked(Range range, bool locked, IPeripheral context = null)290 public virtual void SetAddressRangeLocked(Range range, bool locked, IPeripheral context = null) 291 { 292 ParentController.SetAddressRangeLocked(range, locked, context); 293 } 294 DisablePeripheral(IPeripheral peripheral)295 public virtual void DisablePeripheral(IPeripheral peripheral) 296 { 297 ParentController.DisablePeripheral(peripheral); 298 } 299 EnablePeripheral(IPeripheral peripheral)300 public virtual void EnablePeripheral(IPeripheral peripheral) 301 { 302 ParentController.EnablePeripheral(peripheral); 303 } 304 SetPeripheralEnabled(IPeripheral peripheral, bool enabled)305 public virtual void SetPeripheralEnabled(IPeripheral peripheral, bool enabled) 306 { 307 ParentController.SetPeripheralEnabled(peripheral, enabled); 308 } 309 TryFindSymbolAt(ulong offset, out string name, out Symbol symbol, ICPU context = null)310 public virtual bool TryFindSymbolAt(ulong offset, out string name, out Symbol symbol, ICPU context = null) 311 { 312 return ParentController.TryFindSymbolAt(offset, out name, out symbol, context); 313 } 314 ReadQuadWord(ulong address, IPeripheral context = null, ulong? cpuState = null)315 public virtual ulong ReadQuadWord(ulong address, IPeripheral context = null, ulong? cpuState = null) 316 { 317 return ParentController.ReadQuadWord(address, context, cpuState); 318 } 319 ReadQuadWordWithState(ulong address, IPeripheral context, IContextState stateObj)320 public virtual ulong ReadQuadWordWithState(ulong address, IPeripheral context, IContextState stateObj) 321 { 322 return ParentController.ReadQuadWordWithState(address, context, stateObj); 323 } 324 WriteQuadWord(ulong address, ulong value, IPeripheral context = null, ulong? cpuState = null)325 public virtual void WriteQuadWord(ulong address, ulong value, IPeripheral context = null, ulong? cpuState = null) 326 { 327 ParentController.WriteQuadWord(address, value, context, cpuState); 328 } 329 WriteQuadWordWithState(ulong address, ulong value, IPeripheral context, IContextState stateObj)330 public virtual void WriteQuadWordWithState(ulong address, ulong value, IPeripheral context, IContextState stateObj) 331 { 332 ParentController.WriteQuadWordWithState(address, value, context, stateObj); 333 } 334 IsPeripheralEnabled(IPeripheral peripheral)335 public virtual bool IsPeripheralEnabled(IPeripheral peripheral) 336 { 337 return ParentController.IsPeripheralEnabled(peripheral); 338 } 339 Register(IBusPeripheral peripheral, BusRangeRegistration registrationPoint)340 public virtual void Register(IBusPeripheral peripheral, BusRangeRegistration registrationPoint) 341 { 342 ParentController.Register(peripheral, registrationPoint); 343 } 344 Register(IKnownSize peripheral, BusPointRegistration registrationPoint)345 public virtual void Register(IKnownSize peripheral, BusPointRegistration registrationPoint) 346 { 347 ParentController.Register(peripheral, registrationPoint); 348 } 349 Register(IBusPeripheral peripheral, BusMultiRegistration registrationPoint)350 public virtual void Register(IBusPeripheral peripheral, BusMultiRegistration registrationPoint) 351 { 352 ParentController.Register(peripheral, registrationPoint); 353 } 354 Register(IBusPeripheral peripheral, BusParametrizedRegistration registrationPoint)355 public virtual void Register(IBusPeripheral peripheral, BusParametrizedRegistration registrationPoint) 356 { 357 ParentController.Register(peripheral, registrationPoint); 358 } 359 EnableAllTranslations(bool enable = true)360 public virtual void EnableAllTranslations(bool enable = true) 361 { 362 ParentController.EnableAllTranslations(enable); 363 } 364 EnableAllTranslations(IBusPeripheral busPeripheral, bool enable = true)365 public virtual void EnableAllTranslations(IBusPeripheral busPeripheral, bool enable = true) 366 { 367 ParentController.EnableAllTranslations(busPeripheral, enable); 368 } 369 MoveRegistrationWithinContext(IBusPeripheral peripheral, BusRangeRegistration newRegistration, ICPU context, Func<IEnumerable<IBusRegistered<IBusPeripheral>>, IBusRegistered<IBusPeripheral>> selector = null)370 public void MoveRegistrationWithinContext(IBusPeripheral peripheral, BusRangeRegistration newRegistration, ICPU context, Func<IEnumerable<IBusRegistered<IBusPeripheral>>, IBusRegistered<IBusPeripheral>> selector = null) 371 { 372 ParentController.MoveRegistrationWithinContext(peripheral, newRegistration, context, selector); 373 } 374 Unregister(IBusPeripheral peripheral)375 void IPeripheralRegister<IBusPeripheral, BusMultiRegistration>.Unregister(IBusPeripheral peripheral) 376 { 377 ((IPeripheralRegister<IBusPeripheral, BusMultiRegistration>)ParentController).Unregister(peripheral); 378 } 379 Unregister(IBusPeripheral peripheral)380 void IPeripheralRegister<IBusPeripheral, BusRangeRegistration>.Unregister(IBusPeripheral peripheral) 381 { 382 ((IPeripheralRegister<IBusPeripheral, BusRangeRegistration>)ParentController).Unregister(peripheral); 383 } 384 Unregister(IBusPeripheral peripheral)385 void IPeripheralRegister<IBusPeripheral, BusParametrizedRegistration>.Unregister(IBusPeripheral peripheral) 386 { 387 ((IPeripheralRegister<IBusPeripheral, BusParametrizedRegistration>)ParentController).Unregister(peripheral); 388 } 389 Unregister(IPeripheral peripheral)390 public void Unregister(IPeripheral peripheral) 391 { 392 ParentController.Unregister(peripheral); 393 } 394 Register(IPeripheral peripheral, NullRegistrationPoint registrationPoint)395 public void Register(IPeripheral peripheral, NullRegistrationPoint registrationPoint) 396 { 397 ParentController.Register(peripheral, registrationPoint); 398 } 399 Unregister(ICPU peripheral)400 public virtual void Unregister(ICPU peripheral) 401 { 402 ParentController.Unregister(peripheral); 403 } 404 Unregister(IKnownSize peripheral)405 public virtual void Unregister(IKnownSize peripheral) 406 { 407 ParentController.Unregister(peripheral); 408 } 409 ZeroRange(Range range, IPeripheral context = null)410 public virtual void ZeroRange(Range range, IPeripheral context = null) 411 { 412 ParentController.ZeroRange(range, context); 413 } 414 Register(ICPU cpu, CPURegistrationPoint registrationPoint)415 public virtual void Register(ICPU cpu, CPURegistrationPoint registrationPoint) 416 { 417 ParentController.Register(cpu, registrationPoint); 418 } 419 UnregisterFromAddress(ulong address, ICPU context = null)420 public virtual void UnregisterFromAddress(ulong address, ICPU context = null) 421 { 422 ParentController.UnregisterFromAddress(address, context); 423 } 424 FindMemory(ulong address, ICPU context = null)425 public virtual IBusRegistered<MappedMemory> FindMemory(ulong address, ICPU context = null) 426 { 427 return ParentController.FindMemory(address, context); 428 } 429 IsMemory(ulong address, ICPU context = null)430 public virtual bool IsMemory(ulong address, ICPU context = null) 431 { 432 return ParentController.IsMemory(address, context); 433 } 434 LoadFileChunks(string path, IEnumerable<FileChunk> chunks, ICPU cpu)435 public virtual void LoadFileChunks(string path, IEnumerable<FileChunk> chunks, ICPU cpu) 436 { 437 ParentController.LoadFileChunks(path, chunks, cpu); 438 } 439 Tag(Range range, string tag, ulong defaultValue = 0, bool pausing = false)440 public virtual void Tag(Range range, string tag, ulong defaultValue = 0, bool pausing = false) 441 { 442 ParentController.Tag(range, tag, defaultValue, pausing); 443 } 444 ApplySVD(string path)445 public virtual void ApplySVD(string path) 446 { 447 ParentController.ApplySVD(path); 448 } 449 LoadSymbolsFrom(IELF elf, bool useVirtualAddress = false, ulong? textAddress = null, ICPU context = null)450 public void LoadSymbolsFrom(IELF elf, bool useVirtualAddress = false, ulong? textAddress = null, ICPU context = null) 451 { 452 ParentController.LoadSymbolsFrom(elf, useVirtualAddress, textAddress, context); 453 } 454 LoadUImage(ReadFilePath fileName, IInitableCPU cpu = null)455 public virtual void LoadUImage(ReadFilePath fileName, IInitableCPU cpu = null) 456 { 457 ParentController.LoadUImage(fileName, cpu); 458 } 459 RemoveAllWatchpointHooks(ulong address)460 public virtual void RemoveAllWatchpointHooks(ulong address) 461 { 462 ParentController.RemoveAllWatchpointHooks(address); 463 } 464 MapMemory(IMappedSegment segment, IBusPeripheral owner, bool relative = true, ICPUWithMappedMemory context = null)465 public virtual void MapMemory(IMappedSegment segment, IBusPeripheral owner, bool relative = true, ICPUWithMappedMemory context = null) 466 { 467 ParentController.MapMemory(segment, owner, relative, context); 468 } 469 GetLookup(ICPU context = null)470 public virtual SymbolLookup GetLookup(ICPU context = null) 471 { 472 return ParentController.GetLookup(context); 473 } 474 TryGetAllSymbolAddresses(string symbolName, out IEnumerable<ulong> symbolAddresses, ICPU context = null)475 public virtual bool TryGetAllSymbolAddresses(string symbolName, out IEnumerable<ulong> symbolAddresses, ICPU context = null) 476 { 477 return ParentController.TryGetAllSymbolAddresses(symbolName, out symbolAddresses, context); 478 } 479 480 public virtual IMachine Machine => ParentController.Machine; 481 482 public virtual IEnumerable<IRegistered<IBusPeripheral, BusRangeRegistration>> Children => ParentController.Children; 483 484 public virtual bool IsMultiCore => ParentController.IsMultiCore; 485 486 public virtual IBusController ParentController { get; protected set; } 487 488 public virtual Endianess Endianess => ParentController.Endianess; 489 ValidateOperation(ref ulong address, BusAccessPrivileges accessType, IPeripheral context = null)490 protected virtual bool ValidateOperation(ref ulong address, BusAccessPrivileges accessType, IPeripheral context = null) 491 { 492 return true; 493 } 494 495 event Action<IMachine> IBusController.OnSymbolsChanged 496 { 497 add 498 { 499 ParentController.OnSymbolsChanged += value; 500 } 501 502 remove 503 { 504 ParentController.OnSymbolsChanged -= value; 505 } 506 } 507 } 508 } 509