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