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