1 // 2 // Copyright (c) 2010-2022 Antmicro 3 // 4 // This file is licensed under the MIT License. 5 // Full license text is available in 'licenses/MIT.txt'. 6 // 7 using Antmicro.Renode.Logging; 8 using System.Collections.Generic; 9 using System.Linq; 10 11 namespace Antmicro.Renode.Peripherals.Miscellaneous.Crypto 12 { 13 public class InternalMemoryManager 14 { InternalMemoryManager()15 public InternalMemoryManager() 16 { 17 coreMemories = new Dictionary<long, InternalMemoryAccessor> 18 { 19 { 0x0, new InternalMemoryAccessor(BERLength, "BER_BE", Endianness.BigEndian) }, 20 { 0x1, new InternalMemoryAccessor(MMRLength, "MMR_BE", Endianness.BigEndian) }, 21 { 0x2, new InternalMemoryAccessor(TSRLength, "TSR_BE", Endianness.BigEndian) }, 22 { 0x3, new InternalMemoryAccessor(FPRLength, "FPR_BE", Endianness.BigEndian) }, 23 { 0x8, new InternalMemoryAccessor(BERLength, "BER_LE", Endianness.LittleEndian) }, 24 { 0x9, new InternalMemoryAccessor(MMRLength, "MMR_LE", Endianness.LittleEndian) }, 25 { 0xA, new InternalMemoryAccessor(TSRLength, "TSR_LE", Endianness.LittleEndian) }, 26 { 0xB, new InternalMemoryAccessor(FPRLength, "FPR_LE", Endianness.LittleEndian) } 27 }; 28 } 29 ResetMemories()30 public void ResetMemories() 31 { 32 foreach(var memory in coreMemories) 33 { 34 memory.Value.Reset(); 35 } 36 } 37 TryReadDoubleWord(long offset, out uint result)38 public bool TryReadDoubleWord(long offset, out uint result) 39 { 40 if(!TryAddressInternalMemory(offset, out var mem, out var internalOffset)) 41 { 42 result = 0; 43 return false; 44 } 45 result = mem.ReadDoubleWord(internalOffset); 46 return true; 47 } 48 TryReadBytes(long offset, int count, out byte[] result)49 public bool TryReadBytes(long offset, int count, out byte[] result) 50 { 51 if(!TryAddressInternalMemory(offset, out var mem, out var internalOffset)) 52 { 53 result = new byte[0]; 54 return false; 55 } 56 57 result = mem.ReadBytes(internalOffset, count).ToArray(); 58 return true; 59 } 60 TryWriteDoubleWord(long offset, uint value)61 public bool TryWriteDoubleWord(long offset, uint value) 62 { 63 if(!TryAddressInternalMemory(offset, out var mem, out var internalOffset)) 64 { 65 return false; 66 } 67 mem.WriteDoubleWord(internalOffset, value); 68 return true; 69 } 70 TryWriteBytes(long offset, byte[] bytes)71 public bool TryWriteBytes(long offset, byte[] bytes) 72 { 73 if(!TryAddressInternalMemory(offset, out var mem, out var internalOffset)) 74 { 75 return false; 76 } 77 mem.WriteBytes(internalOffset, bytes); 78 return true; 79 } 80 TryAddressInternalMemory(long offset, out InternalMemoryAccessor mem, out long internalMemoryOffset)81 private bool TryAddressInternalMemory(long offset, out InternalMemoryAccessor mem, out long internalMemoryOffset) 82 { 83 var offsetMask = offset >> OffsetShift; 84 if(!coreMemories.TryGetValue(offsetMask, out mem)) 85 { 86 internalMemoryOffset = 0; 87 Logger.Log(LogLevel.Noisy, "Could not write to internal memory at address 0x{0:X}", offset); 88 return false; 89 } 90 internalMemoryOffset = offset - (offsetMask << OffsetShift); 91 return true; 92 } 93 94 private readonly Dictionary<long, InternalMemoryAccessor> coreMemories; 95 96 private const int BERLength = 0x1000; 97 private const int MMRLength = 0x1000; 98 private const int TSRLength = 0x1000; 99 private const int FPRLength = 0x1000; 100 private const int OffsetShift = 12; 101 } 102 } 103