1 // 2 // Copyright (c) 2010-2023 Antmicro 3 // 4 // This file is licensed under the MIT License. 5 // Full license text is available in 'licenses/MIT.txt'. 6 // 7 using System; 8 using System.Linq; 9 using System.Collections.Generic; 10 using Antmicro.Renode.Core; 11 using Antmicro.Renode.Core.Structure.Registers; 12 using Antmicro.Renode.Logging; 13 using Antmicro.Renode.Logging.Profiling; 14 using Antmicro.Renode.Peripherals.Bus; 15 using Antmicro.Renode.Peripherals.CPU; 16 using Antmicro.Renode.Peripherals.Memory; 17 18 namespace Antmicro.Renode.Peripherals.MTD 19 { 20 public abstract class STM32_FlashController : BasicDoubleWordPeripheral 21 { STM32_FlashController(IMachine machine)22 public STM32_FlashController(IMachine machine) : base(machine) 23 { 24 } 25 26 protected class LockRegister 27 { LockRegister(STM32_FlashController owner, string name, uint[] keys, bool unlockedAfterReset = false)28 public LockRegister(STM32_FlashController owner, string name, uint[] keys, bool unlockedAfterReset = false) 29 { 30 this.owner = owner; 31 this.name = name; 32 this.keys = keys; 33 this.unlockedAfterReset = unlockedAfterReset; 34 IsLocked = this.unlockedAfterReset ? false : true; 35 } 36 ConsumeValue(uint value)37 public void ConsumeValue(uint value) 38 { 39 owner.Log(LogLevel.Debug, "Lock {0} received 0x{1:x8}", name, value); 40 if(DisabledUntilReset) 41 { 42 owner.Log(LogLevel.Debug, "Lock {0} is disabled until reset, ignoring", name); 43 return; 44 } 45 46 if(keyIndex >= keys.Length || keys[keyIndex] != value) 47 { 48 owner.Log(LogLevel.Debug, "Lock {0} now disabled until reset after bad write", name); 49 Lock(); 50 DisabledUntilReset = true; 51 return; 52 } 53 54 if(++keyIndex == keys.Length) 55 { 56 IsLocked = false; 57 owner.Log(LogLevel.Debug, "Lock {0} unlocked", name); 58 } 59 } 60 Lock()61 public void Lock() 62 { 63 if(IsLocked) 64 { 65 return; 66 } 67 68 owner.Log(LogLevel.Debug, "Lock {0} locked", name); 69 IsLocked = true; 70 keyIndex = 0; 71 Locked?.Invoke(); 72 } 73 Reset()74 public void Reset() 75 { 76 if(unlockedAfterReset) 77 { 78 IsLocked = false; 79 } 80 else 81 { 82 Lock(); 83 } 84 DisabledUntilReset = false; 85 } 86 87 public bool IsLocked { get; private set; } 88 public bool DisabledUntilReset { get; private set; } 89 public event Action Locked; 90 91 private readonly STM32_FlashController owner; 92 private readonly string name; 93 private readonly uint[] keys; 94 private readonly bool unlockedAfterReset; 95 private int keyIndex; 96 } 97 } 98 } 99