1 //
2 // Copyright (c) 2010-2023 Antmicro
3 // Copyright (c) 2011-2015 Realtime Embedded
4 //
5 // This file is licensed under the MIT License.
6 // Full license text is available in 'licenses/MIT.txt'.
7 //
8 using System;
9 using System.Collections.Generic;
10 using Antmicro.Renode.Core;
11 using System.Linq;
12 using Antmicro.Renode.Exceptions;
13 using Antmicro.Renode.Peripherals.CPU;
14 using Antmicro.Renode.Utilities;
15 
16 namespace Antmicro.Renode.Peripherals.Bus
17 {
18     public static class RedirectorExtensions
19     {
Redirect(this IBusController sysbus, ulong from, ulong to, ulong size)20         public static void Redirect(this IBusController sysbus, ulong from, ulong to, ulong size)
21         {
22             var redirector = new Redirector(sysbus.Machine, to);
23             var rangePoint = new BusRangeRegistration(from.By(size));
24             sysbus.Register(redirector, rangePoint);
25         }
26     }
27 
28     public sealed class Redirector : IBytePeripheral, IWordPeripheral, IDoubleWordPeripheral, IMultibyteWritePeripheral, ICanLoadFiles
29     {
Redirector(IMachine machine, ulong redirectedAddress)30         public Redirector(IMachine machine, ulong redirectedAddress)
31         {
32             this.redirectedAddress = redirectedAddress;
33             systemBus = machine.GetSystemBus(this);
34         }
35 
ReadByte(long offset)36         public byte ReadByte(long offset)
37         {
38             return systemBus.ReadByte(redirectedAddress + checked((ulong)offset));
39         }
40 
WriteByte(long offset, byte value)41         public void WriteByte(long offset, byte value)
42         {
43             systemBus.WriteByte(redirectedAddress + checked((ulong)offset), value);
44         }
45 
ReadWord(long offset)46         public ushort ReadWord(long offset)
47         {
48             return systemBus.ReadWord(redirectedAddress + checked((ulong)offset));
49         }
50 
WriteWord(long offset, ushort value)51         public void WriteWord(long offset, ushort value)
52         {
53             systemBus.WriteWord(checked((ulong)offset), value);
54         }
55 
ReadDoubleWord(long offset)56         public uint ReadDoubleWord(long offset)
57         {
58             return systemBus.ReadDoubleWord(redirectedAddress + checked((ulong)offset));
59         }
60 
WriteDoubleWord(long offset, uint value)61         public void WriteDoubleWord(long offset, uint value)
62         {
63             systemBus.WriteDoubleWord(redirectedAddress + checked((ulong)offset), value);
64         }
65 
TranslateAbsolute(ulong address)66         public ulong TranslateAbsolute(ulong address)
67         {
68             foreach(var range in systemBus.GetRegistrationPoints(this).Select(x => x.Range))
69             {
70                 if(range.Contains(address))
71                 {
72                     return address - range.StartAddress + redirectedAddress;
73                 }
74             }
75             throw new RecoverableException("Cannot translate address that does not lay in redirector.");
76         }
77 
ReadBytes(long offset, int count, IPeripheral context = null)78         public byte[] ReadBytes(long offset, int count, IPeripheral context = null)
79         {
80             return systemBus.ReadBytes(redirectedAddress + checked((ulong)offset), count, context: context);
81         }
82 
WriteBytes(long offset, byte[] array, int startingIndex, int count, IPeripheral context = null)83         public void WriteBytes(long offset, byte[] array, int startingIndex, int count, IPeripheral context = null)
84         {
85             systemBus.WriteBytes(array, redirectedAddress + checked((ulong)offset), count, context: context);
86         }
87 
LoadFileChunks(string path, IEnumerable<FileChunk> chunks, ICPU cpu)88         public void LoadFileChunks(string path, IEnumerable<FileChunk> chunks, ICPU cpu)
89         {
90             this.LoadFileChunks(chunks, cpu);
91         }
92 
Reset()93         public void Reset()
94         {
95 
96         }
97 
98         private readonly ulong redirectedAddress;
99         private readonly IBusController systemBus;
100     }
101 }
102 
103