1 /********************************************************
2 *
3 * Warning!
4 * This file was generated automatically.
5 * Please do not edit. Changes should be made in the
6 * appropriate *.tt file.
7 *
8 */
9 
10 using System;
11 using Antmicro.Renode.Core;
12 using Antmicro.Renode.Exceptions;
13 using Antmicro.Renode.Logging;
14 using Antmicro.Renode.Peripherals.Bus.Wrappers;
15 using Antmicro.Renode.Peripherals.CPU;
16 
17 using Range = Antmicro.Renode.Core.Range;
18 
19 namespace Antmicro.Renode.Peripherals.Bus
20 {
21     public partial class SystemBus
22     {
ReadByte(ulong address, IPeripheral context = null, ulong? cpuState = null)23         public byte ReadByte(ulong address, IPeripheral context = null, ulong? cpuState = null)
24         {
25             var accessWidth = SysbusAccessWidth.Byte;
26             if(IsAddressRangeLocked(address.By((ulong)accessWidth), context))
27             {
28                 this.Log(LogLevel.Warning, "Tried to read {0} bytes at 0x{1:X} which is inside a locked address range, returning 0",
29                     (uint)accessWidth, address);
30                 return 0;
31             }
32 
33             using(SetLocalContext(context, cpuState))
34             {
35                 if(!TryFindPeripheralAccessMethods(address, context, out var accessMethods, out var startAddress, cpuState))
36                 {
37                     return (byte)ReportNonExistingRead(address, accessWidth);
38                 }
39                 if(!IsPeripheralEnabled(accessMethods.Peripheral))
40                 {
41                     this.Log(LogLevel.Warning, "Tried to read a locked peripheral: {0}. Address 0x{1:X}.", accessMethods.Peripheral, address);
42                     return 0;
43                 }
44                 var lockTaken = false;
45                 try
46                 {
47                     if(!accessMethods.Lock.IsHeldByCurrentThread)
48                     {
49                         accessMethods.Lock.Enter(ref lockTaken);
50                     }
51                     if(accessMethods.SetAbsoluteAddress != null)
52                     {
53                         accessMethods.SetAbsoluteAddress(address);
54                     }
55                     return accessMethods.ReadByte(checked((long)(address - startAddress)));
56                 }
57                 finally
58                 {
59                     if(lockTaken)
60                     {
61                         accessMethods.Lock.Exit();
62                     }
63                 }
64             }
65         }
66 
ReadByteWithState(ulong address, IPeripheral context, IContextState stateObj)67         public byte ReadByteWithState(ulong address, IPeripheral context, IContextState stateObj)
68         {
69             var accessWidth = SysbusAccessWidth.Byte;
70             if(!TryConvertStateToUlongForContext(context, stateObj, out ulong? state))
71             {
72                 this.Log(LogLevel.Warning, "Tried to read {0} bytes at 0x{1:X} but failed on context state conversion, returning 0",
73                     (uint)accessWidth, address);
74                 return 0;
75             }
76             return ReadByte(address, context, state);
77         }
78 
WriteByte(ulong address, byte value, IPeripheral context = null, ulong? cpuState = null)79         public void WriteByte(ulong address, byte value, IPeripheral context = null, ulong? cpuState = null)
80         {
81             var accessWidth = SysbusAccessWidth.Byte;
82             if(IsAddressRangeLocked(address.By((ulong)accessWidth), context))
83             {
84                 this.Log(LogLevel.Warning, "Tried to write {0} bytes (0x{1:X}) at 0x{2:X} which is inside a locked address range, write ignored",
85                     (uint)accessWidth, value, address);
86                 return;
87             }
88 
89             using(SetLocalContext(context, cpuState))
90             {
91                 if(!TryFindPeripheralAccessMethods(address, context, out var accessMethods, out var startAddress, cpuState))
92                 {
93                     ReportNonExistingWrite(address, value, accessWidth);
94                     return;
95                 }
96                 if(!IsPeripheralEnabled(accessMethods.Peripheral))
97                 {
98                     this.Log(LogLevel.Warning, "Tried to write a locked peripheral: {0}. Address 0x{1:X}, value 0x{2:X}", accessMethods.Peripheral, address, value);
99                     return;
100                 }
101 
102                 var lockTaken = false;
103                 try
104                 {
105                     if(!accessMethods.Lock.IsHeldByCurrentThread)
106                     {
107                         accessMethods.Lock.Enter(ref lockTaken);
108                     }
109                     if(accessMethods.SetAbsoluteAddress != null)
110                     {
111                         accessMethods.SetAbsoluteAddress(address);
112                     }
113                     accessMethods.WriteByte(checked((long)(address - startAddress)), value);
114                 }
115                 finally
116                 {
117                     if(lockTaken)
118                     {
119                         accessMethods.Lock.Exit();
120                     }
121                 }
122             }
123         }
124 
WriteByteWithState(ulong address, byte value, IPeripheral context, IContextState stateObj)125         public void WriteByteWithState(ulong address, byte value, IPeripheral context, IContextState stateObj)
126         {
127             var accessWidth = SysbusAccessWidth.Byte;
128             if(!TryConvertStateToUlongForContext(context, stateObj, out ulong? state))
129             {
130                 this.Log(LogLevel.Warning, "Tried to write {0} bytes (0x{1:X}) at 0x{2:X} but failed on context state conversion, write ignored",
131                     (uint)accessWidth, value, address);
132                 return;
133             }
134             WriteByte(address, value, context, state);
135         }
136 
ReadWord(ulong address, IPeripheral context = null, ulong? cpuState = null)137         public ushort ReadWord(ulong address, IPeripheral context = null, ulong? cpuState = null)
138         {
139             var accessWidth = SysbusAccessWidth.Word;
140             if(IsAddressRangeLocked(address.By((ulong)accessWidth), context))
141             {
142                 this.Log(LogLevel.Warning, "Tried to read {0} bytes at 0x{1:X} which is inside a locked address range, returning 0",
143                     (uint)accessWidth, address);
144                 return 0;
145             }
146 
147             using(SetLocalContext(context, cpuState))
148             {
149                 if(!TryFindPeripheralAccessMethods(address, context, out var accessMethods, out var startAddress, cpuState))
150                 {
151                     return (ushort)ReportNonExistingRead(address, accessWidth);
152                 }
153                 if(!IsPeripheralEnabled(accessMethods.Peripheral))
154                 {
155                     this.Log(LogLevel.Warning, "Tried to read a locked peripheral: {0}. Address 0x{1:X}.", accessMethods.Peripheral, address);
156                     return 0;
157                 }
158                 var lockTaken = false;
159                 try
160                 {
161                     if(!accessMethods.Lock.IsHeldByCurrentThread)
162                     {
163                         accessMethods.Lock.Enter(ref lockTaken);
164                     }
165                     if(accessMethods.SetAbsoluteAddress != null)
166                     {
167                         accessMethods.SetAbsoluteAddress(address);
168                     }
169                     return accessMethods.ReadWord(checked((long)(address - startAddress)));
170                 }
171                 finally
172                 {
173                     if(lockTaken)
174                     {
175                         accessMethods.Lock.Exit();
176                     }
177                 }
178             }
179         }
180 
ReadWordWithState(ulong address, IPeripheral context, IContextState stateObj)181         public ushort ReadWordWithState(ulong address, IPeripheral context, IContextState stateObj)
182         {
183             var accessWidth = SysbusAccessWidth.Word;
184             if(!TryConvertStateToUlongForContext(context, stateObj, out ulong? state))
185             {
186                 this.Log(LogLevel.Warning, "Tried to read {0} bytes at 0x{1:X} but failed on context state conversion, returning 0",
187                     (uint)accessWidth, address);
188                 return 0;
189             }
190             return ReadWord(address, context, state);
191         }
192 
WriteWord(ulong address, ushort value, IPeripheral context = null, ulong? cpuState = null)193         public void WriteWord(ulong address, ushort value, IPeripheral context = null, ulong? cpuState = null)
194         {
195             var accessWidth = SysbusAccessWidth.Word;
196             if(IsAddressRangeLocked(address.By((ulong)accessWidth), context))
197             {
198                 this.Log(LogLevel.Warning, "Tried to write {0} bytes (0x{1:X}) at 0x{2:X} which is inside a locked address range, write ignored",
199                     (uint)accessWidth, value, address);
200                 return;
201             }
202 
203             using(SetLocalContext(context, cpuState))
204             {
205                 if(!TryFindPeripheralAccessMethods(address, context, out var accessMethods, out var startAddress, cpuState))
206                 {
207                     ReportNonExistingWrite(address, value, accessWidth);
208                     return;
209                 }
210                 if(!IsPeripheralEnabled(accessMethods.Peripheral))
211                 {
212                     this.Log(LogLevel.Warning, "Tried to write a locked peripheral: {0}. Address 0x{1:X}, value 0x{2:X}", accessMethods.Peripheral, address, value);
213                     return;
214                 }
215 
216                 var lockTaken = false;
217                 try
218                 {
219                     if(!accessMethods.Lock.IsHeldByCurrentThread)
220                     {
221                         accessMethods.Lock.Enter(ref lockTaken);
222                     }
223                     if(accessMethods.SetAbsoluteAddress != null)
224                     {
225                         accessMethods.SetAbsoluteAddress(address);
226                     }
227                     accessMethods.WriteWord(checked((long)(address - startAddress)), value);
228                 }
229                 finally
230                 {
231                     if(lockTaken)
232                     {
233                         accessMethods.Lock.Exit();
234                     }
235                 }
236             }
237         }
238 
WriteWordWithState(ulong address, ushort value, IPeripheral context, IContextState stateObj)239         public void WriteWordWithState(ulong address, ushort value, IPeripheral context, IContextState stateObj)
240         {
241             var accessWidth = SysbusAccessWidth.Word;
242             if(!TryConvertStateToUlongForContext(context, stateObj, out ulong? state))
243             {
244                 this.Log(LogLevel.Warning, "Tried to write {0} bytes (0x{1:X}) at 0x{2:X} but failed on context state conversion, write ignored",
245                     (uint)accessWidth, value, address);
246                 return;
247             }
248             WriteWord(address, value, context, state);
249         }
250 
ReadDoubleWord(ulong address, IPeripheral context = null, ulong? cpuState = null)251         public uint ReadDoubleWord(ulong address, IPeripheral context = null, ulong? cpuState = null)
252         {
253             var accessWidth = SysbusAccessWidth.DoubleWord;
254             if(IsAddressRangeLocked(address.By((ulong)accessWidth), context))
255             {
256                 this.Log(LogLevel.Warning, "Tried to read {0} bytes at 0x{1:X} which is inside a locked address range, returning 0",
257                     (uint)accessWidth, address);
258                 return 0;
259             }
260 
261             using(SetLocalContext(context, cpuState))
262             {
263                 if(!TryFindPeripheralAccessMethods(address, context, out var accessMethods, out var startAddress, cpuState))
264                 {
265                     return (uint)ReportNonExistingRead(address, accessWidth);
266                 }
267                 if(!IsPeripheralEnabled(accessMethods.Peripheral))
268                 {
269                     this.Log(LogLevel.Warning, "Tried to read a locked peripheral: {0}. Address 0x{1:X}.", accessMethods.Peripheral, address);
270                     return 0;
271                 }
272                 var lockTaken = false;
273                 try
274                 {
275                     if(!accessMethods.Lock.IsHeldByCurrentThread)
276                     {
277                         accessMethods.Lock.Enter(ref lockTaken);
278                     }
279                     if(accessMethods.SetAbsoluteAddress != null)
280                     {
281                         accessMethods.SetAbsoluteAddress(address);
282                     }
283                     return accessMethods.ReadDoubleWord(checked((long)(address - startAddress)));
284                 }
285                 finally
286                 {
287                     if(lockTaken)
288                     {
289                         accessMethods.Lock.Exit();
290                     }
291                 }
292             }
293         }
294 
ReadDoubleWordWithState(ulong address, IPeripheral context, IContextState stateObj)295         public uint ReadDoubleWordWithState(ulong address, IPeripheral context, IContextState stateObj)
296         {
297             var accessWidth = SysbusAccessWidth.DoubleWord;
298             if(!TryConvertStateToUlongForContext(context, stateObj, out ulong? state))
299             {
300                 this.Log(LogLevel.Warning, "Tried to read {0} bytes at 0x{1:X} but failed on context state conversion, returning 0",
301                     (uint)accessWidth, address);
302                 return 0;
303             }
304             return ReadDoubleWord(address, context, state);
305         }
306 
WriteDoubleWord(ulong address, uint value, IPeripheral context = null, ulong? cpuState = null)307         public void WriteDoubleWord(ulong address, uint value, IPeripheral context = null, ulong? cpuState = null)
308         {
309             var accessWidth = SysbusAccessWidth.DoubleWord;
310             if(IsAddressRangeLocked(address.By((ulong)accessWidth), context))
311             {
312                 this.Log(LogLevel.Warning, "Tried to write {0} bytes (0x{1:X}) at 0x{2:X} which is inside a locked address range, write ignored",
313                     (uint)accessWidth, value, address);
314                 return;
315             }
316 
317             using(SetLocalContext(context, cpuState))
318             {
319                 if(!TryFindPeripheralAccessMethods(address, context, out var accessMethods, out var startAddress, cpuState))
320                 {
321                     ReportNonExistingWrite(address, value, accessWidth);
322                     return;
323                 }
324                 if(!IsPeripheralEnabled(accessMethods.Peripheral))
325                 {
326                     this.Log(LogLevel.Warning, "Tried to write a locked peripheral: {0}. Address 0x{1:X}, value 0x{2:X}", accessMethods.Peripheral, address, value);
327                     return;
328                 }
329 
330                 var lockTaken = false;
331                 try
332                 {
333                     if(!accessMethods.Lock.IsHeldByCurrentThread)
334                     {
335                         accessMethods.Lock.Enter(ref lockTaken);
336                     }
337                     if(accessMethods.SetAbsoluteAddress != null)
338                     {
339                         accessMethods.SetAbsoluteAddress(address);
340                     }
341                     accessMethods.WriteDoubleWord(checked((long)(address - startAddress)), value);
342                 }
343                 finally
344                 {
345                     if(lockTaken)
346                     {
347                         accessMethods.Lock.Exit();
348                     }
349                 }
350             }
351         }
352 
WriteDoubleWordWithState(ulong address, uint value, IPeripheral context, IContextState stateObj)353         public void WriteDoubleWordWithState(ulong address, uint value, IPeripheral context, IContextState stateObj)
354         {
355             var accessWidth = SysbusAccessWidth.DoubleWord;
356             if(!TryConvertStateToUlongForContext(context, stateObj, out ulong? state))
357             {
358                 this.Log(LogLevel.Warning, "Tried to write {0} bytes (0x{1:X}) at 0x{2:X} but failed on context state conversion, write ignored",
359                     (uint)accessWidth, value, address);
360                 return;
361             }
362             WriteDoubleWord(address, value, context, state);
363         }
364 
ReadQuadWord(ulong address, IPeripheral context = null, ulong? cpuState = null)365         public ulong ReadQuadWord(ulong address, IPeripheral context = null, ulong? cpuState = null)
366         {
367             var accessWidth = SysbusAccessWidth.QuadWord;
368             if(IsAddressRangeLocked(address.By((ulong)accessWidth), context))
369             {
370                 this.Log(LogLevel.Warning, "Tried to read {0} bytes at 0x{1:X} which is inside a locked address range, returning 0",
371                     (uint)accessWidth, address);
372                 return 0;
373             }
374 
375             using(SetLocalContext(context, cpuState))
376             {
377                 if(!TryFindPeripheralAccessMethods(address, context, out var accessMethods, out var startAddress, cpuState))
378                 {
379                     return (ulong)ReportNonExistingRead(address, accessWidth);
380                 }
381                 if(!IsPeripheralEnabled(accessMethods.Peripheral))
382                 {
383                     this.Log(LogLevel.Warning, "Tried to read a locked peripheral: {0}. Address 0x{1:X}.", accessMethods.Peripheral, address);
384                     return 0;
385                 }
386                 var lockTaken = false;
387                 try
388                 {
389                     if(!accessMethods.Lock.IsHeldByCurrentThread)
390                     {
391                         accessMethods.Lock.Enter(ref lockTaken);
392                     }
393                     if(accessMethods.SetAbsoluteAddress != null)
394                     {
395                         accessMethods.SetAbsoluteAddress(address);
396                     }
397                     return accessMethods.ReadQuadWord(checked((long)(address - startAddress)));
398                 }
399                 finally
400                 {
401                     if(lockTaken)
402                     {
403                         accessMethods.Lock.Exit();
404                     }
405                 }
406             }
407         }
408 
ReadQuadWordWithState(ulong address, IPeripheral context, IContextState stateObj)409         public ulong ReadQuadWordWithState(ulong address, IPeripheral context, IContextState stateObj)
410         {
411             var accessWidth = SysbusAccessWidth.QuadWord;
412             if(!TryConvertStateToUlongForContext(context, stateObj, out ulong? state))
413             {
414                 this.Log(LogLevel.Warning, "Tried to read {0} bytes at 0x{1:X} but failed on context state conversion, returning 0",
415                     (uint)accessWidth, address);
416                 return 0;
417             }
418             return ReadQuadWord(address, context, state);
419         }
420 
WriteQuadWord(ulong address, ulong value, IPeripheral context = null, ulong? cpuState = null)421         public void WriteQuadWord(ulong address, ulong value, IPeripheral context = null, ulong? cpuState = null)
422         {
423             var accessWidth = SysbusAccessWidth.QuadWord;
424             if(IsAddressRangeLocked(address.By((ulong)accessWidth), context))
425             {
426                 this.Log(LogLevel.Warning, "Tried to write {0} bytes (0x{1:X}) at 0x{2:X} which is inside a locked address range, write ignored",
427                     (uint)accessWidth, value, address);
428                 return;
429             }
430 
431             using(SetLocalContext(context, cpuState))
432             {
433                 if(!TryFindPeripheralAccessMethods(address, context, out var accessMethods, out var startAddress, cpuState))
434                 {
435                     ReportNonExistingWrite(address, value, accessWidth);
436                     return;
437                 }
438                 if(!IsPeripheralEnabled(accessMethods.Peripheral))
439                 {
440                     this.Log(LogLevel.Warning, "Tried to write a locked peripheral: {0}. Address 0x{1:X}, value 0x{2:X}", accessMethods.Peripheral, address, value);
441                     return;
442                 }
443 
444                 var lockTaken = false;
445                 try
446                 {
447                     if(!accessMethods.Lock.IsHeldByCurrentThread)
448                     {
449                         accessMethods.Lock.Enter(ref lockTaken);
450                     }
451                     if(accessMethods.SetAbsoluteAddress != null)
452                     {
453                         accessMethods.SetAbsoluteAddress(address);
454                     }
455                     accessMethods.WriteQuadWord(checked((long)(address - startAddress)), value);
456                 }
457                 finally
458                 {
459                     if(lockTaken)
460                     {
461                         accessMethods.Lock.Exit();
462                     }
463                 }
464             }
465         }
466 
WriteQuadWordWithState(ulong address, ulong value, IPeripheral context, IContextState stateObj)467         public void WriteQuadWordWithState(ulong address, ulong value, IPeripheral context, IContextState stateObj)
468         {
469             var accessWidth = SysbusAccessWidth.QuadWord;
470             if(!TryConvertStateToUlongForContext(context, stateObj, out ulong? state))
471             {
472                 this.Log(LogLevel.Warning, "Tried to write {0} bytes (0x{1:X}) at 0x{2:X} but failed on context state conversion, write ignored",
473                     (uint)accessWidth, value, address);
474                 return;
475             }
476             WriteQuadWord(address, value, context, state);
477         }
478 
ClearHookAfterPeripheralRead(IBusPeripheral peripheral)479         public void ClearHookAfterPeripheralRead<T>(IBusPeripheral peripheral)
480         {
481             SetHookAfterPeripheralRead<T>(peripheral, null);
482         }
483 
SetHookAfterPeripheralRead(IBusPeripheral peripheral, Func<T, long, T> hook, Range? subrange = null)484         public void SetHookAfterPeripheralRead<T>(IBusPeripheral peripheral, Func<T, long, T> hook, Range? subrange = null)
485         {
486             if(!Machine.IsRegistered(peripheral))
487             {
488                 throw new RecoverableException(string.Format("Cannot set hook on peripheral {0}, it is not registered.", peripheral));
489             }
490             var type = typeof(T);
491             if(type == typeof(byte))
492             {
493                 foreach(var peripherals in allPeripherals)
494                 {
495                     peripherals.VisitAccessMethods(peripheral, pam =>
496                     {
497                         if(pam.ReadByte.Target is ReadHookWrapper<byte>)
498                         {
499                             pam.ReadByte = new BusAccess.ByteReadMethod(((ReadHookWrapper<byte>)pam.ReadByte.Target).OriginalMethod);
500                         }
501                         if(hook != null)
502                         {
503                             pam.ReadByte = new BusAccess.ByteReadMethod(new ReadHookWrapper<byte>(peripheral, new Func<long, byte>(pam.ReadByte), (Func<byte, long, byte>)(object)hook, subrange).Read);
504                         }
505                         return pam;
506                     });
507                 }
508                 return;
509             }
510             if(type == typeof(ushort))
511             {
512                 foreach(var peripherals in allPeripherals)
513                 {
514                     peripherals.VisitAccessMethods(peripheral, pam =>
515                     {
516                         if(pam.ReadWord.Target is ReadHookWrapper<ushort>)
517                         {
518                             pam.ReadWord = new BusAccess.WordReadMethod(((ReadHookWrapper<ushort>)pam.ReadWord.Target).OriginalMethod);
519                         }
520                         if(hook != null)
521                         {
522                             pam.ReadWord = new BusAccess.WordReadMethod(new ReadHookWrapper<ushort>(peripheral, new Func<long, ushort>(pam.ReadWord), (Func<ushort, long, ushort>)(object)hook, subrange).Read);
523                         }
524                         return pam;
525                     });
526                 }
527                 return;
528             }
529             if(type == typeof(uint))
530             {
531                 foreach(var peripherals in allPeripherals)
532                 {
533                     peripherals.VisitAccessMethods(peripheral, pam =>
534                     {
535                         if(pam.ReadDoubleWord.Target is ReadHookWrapper<uint>)
536                         {
537                             pam.ReadDoubleWord = new BusAccess.DoubleWordReadMethod(((ReadHookWrapper<uint>)pam.ReadDoubleWord.Target).OriginalMethod);
538                         }
539                         if(hook != null)
540                         {
541                             pam.ReadDoubleWord = new BusAccess.DoubleWordReadMethod(new ReadHookWrapper<uint>(peripheral, new Func<long, uint>(pam.ReadDoubleWord), (Func<uint, long, uint>)(object)hook, subrange).Read);
542                         }
543                         return pam;
544                     });
545                 }
546                 return;
547             }
548             if(type == typeof(ulong))
549             {
550                 foreach(var peripherals in allPeripherals)
551                 {
552                     peripherals.VisitAccessMethods(peripheral, pam =>
553                     {
554                         if(pam.ReadQuadWord.Target is ReadHookWrapper<ulong>)
555                         {
556                             pam.ReadQuadWord = new BusAccess.QuadWordReadMethod(((ReadHookWrapper<ulong>)pam.ReadQuadWord.Target).OriginalMethod);
557                         }
558                         if(hook != null)
559                         {
560                             pam.ReadQuadWord = new BusAccess.QuadWordReadMethod(new ReadHookWrapper<ulong>(peripheral, new Func<long, ulong>(pam.ReadQuadWord), (Func<ulong, long, ulong>)(object)hook, subrange).Read);
561                         }
562                         return pam;
563                     });
564                 }
565                 return;
566             }
567         }
568 
ClearHookBeforePeripheralWrite(IBusPeripheral peripheral)569         public void ClearHookBeforePeripheralWrite<T>(IBusPeripheral peripheral)
570         {
571             SetHookBeforePeripheralWrite<T>(peripheral, null);
572         }
573 
SetHookBeforePeripheralWrite(IBusPeripheral peripheral, Func<T, long, T> hook, Range? subrange = null)574         public void SetHookBeforePeripheralWrite<T>(IBusPeripheral peripheral, Func<T, long, T> hook, Range? subrange = null)
575         {
576             if(!Machine.IsRegistered(peripheral))
577             {
578                 throw new RecoverableException(string.Format("Cannot set hook on peripheral {0}, it is not registered.", peripheral));
579             }
580             var type = typeof(T);
581             if(type == typeof(byte))
582             {
583                 foreach(var peripherals in allPeripherals)
584                 {
585                     peripherals.VisitAccessMethods(peripheral, pam =>
586                     {
587                         if(pam.WriteByte.Target is WriteHookWrapper<byte>)
588                         {
589                             pam.WriteByte = new BusAccess.ByteWriteMethod(((WriteHookWrapper<byte>)pam.WriteByte.Target).OriginalMethod);
590                         }
591                         if(hook != null)
592                         {
593                             pam.WriteByte = new BusAccess.ByteWriteMethod(new WriteHookWrapper<byte>(peripheral, new Action<long, byte>(pam.WriteByte), (Func<byte, long, byte>)(object)hook, subrange).Write);
594                         }
595                         return pam;
596                     });
597                 }
598                 return;
599             }
600             if(type == typeof(ushort))
601             {
602                 foreach(var peripherals in allPeripherals)
603                 {
604                     peripherals.VisitAccessMethods(peripheral, pam =>
605                     {
606                         if(pam.WriteWord.Target is WriteHookWrapper<ushort>)
607                         {
608                             pam.WriteWord = new BusAccess.WordWriteMethod(((WriteHookWrapper<ushort>)pam.WriteWord.Target).OriginalMethod);
609                         }
610                         if(hook != null)
611                         {
612                             pam.WriteWord = new BusAccess.WordWriteMethod(new WriteHookWrapper<ushort>(peripheral, new Action<long, ushort>(pam.WriteWord), (Func<ushort, long, ushort>)(object)hook, subrange).Write);
613                         }
614                         return pam;
615                     });
616                 }
617                 return;
618             }
619             if(type == typeof(uint))
620             {
621                 foreach(var peripherals in allPeripherals)
622                 {
623                     peripherals.VisitAccessMethods(peripheral, pam =>
624                     {
625                         if(pam.WriteDoubleWord.Target is WriteHookWrapper<uint>)
626                         {
627                             pam.WriteDoubleWord = new BusAccess.DoubleWordWriteMethod(((WriteHookWrapper<uint>)pam.WriteDoubleWord.Target).OriginalMethod);
628                         }
629                         if(hook != null)
630                         {
631                             pam.WriteDoubleWord = new BusAccess.DoubleWordWriteMethod(new WriteHookWrapper<uint>(peripheral, new Action<long, uint>(pam.WriteDoubleWord), (Func<uint, long, uint>)(object)hook, subrange).Write);
632                         }
633                         return pam;
634                     });
635                 }
636                 return;
637             }
638             if(type == typeof(ulong))
639             {
640                 foreach(var peripherals in allPeripherals)
641                 {
642                     peripherals.VisitAccessMethods(peripheral, pam =>
643                     {
644                         if(pam.WriteQuadWord.Target is WriteHookWrapper<ulong>)
645                         {
646                             pam.WriteQuadWord = new BusAccess.QuadWordWriteMethod(((WriteHookWrapper<ulong>)pam.WriteQuadWord.Target).OriginalMethod);
647                         }
648                         if(hook != null)
649                         {
650                             pam.WriteQuadWord = new BusAccess.QuadWordWriteMethod(new WriteHookWrapper<ulong>(peripheral, new Action<long, ulong>(pam.WriteQuadWord), (Func<ulong, long, ulong>)(object)hook, subrange).Write);
651                         }
652                         return pam;
653                     });
654                 }
655                 return;
656             }
657         }
658 
TryFindPeripheralAccessMethods(ulong address, IPeripheral context, out PeripheralAccessMethods accessMethods, out ulong startAddress, ulong? cpuState = null)659         private bool TryFindPeripheralAccessMethods(ulong address, IPeripheral context, out PeripheralAccessMethods accessMethods, out ulong startAddress, ulong? cpuState = null)
660         {
661             if(context == null)
662             {
663                 TryGetCurrentCPU(out var cpu);
664                 context = cpu;
665             }
666             if(context != null)
667             {
668                 if(peripheralsCollectionByContext.TryGetValue(context, cpuState, out var collection))
669                 {
670                     accessMethods = collection.FindAccessMethods(address, out startAddress, out var _);
671                     if(accessMethods != null)
672                     {
673                         return true;
674                     }
675                 }
676             }
677             accessMethods = peripheralsCollectionByContext[null].FindAccessMethods(address, out startAddress, out _);
678             return accessMethods != null;
679         }
680     }
681 }
682