1 // 2 // Copyright (c) 2010-2019 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.Core; 8 using Antmicro.Renode.Peripherals.Bus; 9 using Antmicro.Renode.Core.Structure.Registers; 10 using Antmicro.Renode.Time; 11 using System; 12 using static Antmicro.Renode.Utilities.BitHelper; 13 using Antmicro.Renode.Utilities; 14 using System.Collections.Generic; 15 using Antmicro.Renode.Logging; 16 17 namespace Antmicro.Renode.Peripherals.Miscellaneous 18 { 19 public class STM32F4_RNG : IDoubleWordPeripheral, IKnownSize 20 { STM32F4_RNG(IMachine machine)21 public STM32F4_RNG(IMachine machine) 22 { 23 IRQ = new GPIO(); 24 25 var registerMap = new Dictionary<long, DoubleWordRegister> 26 { 27 {(long)Registers.Control, new DoubleWordRegister(this) 28 .WithReservedBits(0, 2) 29 .WithFlag(2, out enable, changeCallback: (_, value) => Update(), name: "RNGEN") 30 .WithFlag(3, out interruptEnable, changeCallback: (_, value) => Update(), name: "IE") 31 .WithReservedBits(4, 28) 32 }, 33 {(long)Registers.Status, new DoubleWordRegister(this) 34 .WithFlag(0, FieldMode.Read, valueProviderCallback: _ => enable.Value, name: "DRDY") 35 .WithTag("CECS", 1, 1) 36 .WithTag("SECS", 2, 1) 37 .WithReservedBits(3, 2) 38 .WithTag("CEIS", 5, 1) 39 .WithTag("SEIS", 6, 1) 40 .WithReservedBits(7, 25) 41 }, 42 {(long)Registers.Data, new DoubleWordRegister(this) 43 .WithValueField(0, 32, FieldMode.Read, valueProviderCallback: _ => 44 { 45 if(enable.Value) 46 { 47 return unchecked((uint)rng.Next()); 48 } 49 else 50 { 51 return 0; 52 } 53 }, name: "RNDATA") 54 }, 55 }; 56 registers = new DoubleWordRegisterCollection(this, registerMap); 57 } 58 Reset()59 public void Reset() 60 { 61 registers.Reset(); 62 } 63 ReadDoubleWord(long offset)64 public uint ReadDoubleWord(long offset) 65 { 66 return registers.Read(offset); 67 } 68 WriteDoubleWord(long offset, uint value)69 public void WriteDoubleWord(long offset, uint value) 70 { 71 registers.Write(offset, value); 72 } 73 Update()74 private void Update() 75 { 76 IRQ.Set(enable.Value && interruptEnable.Value); 77 } 78 79 public long Size => 0x400; 80 public GPIO IRQ { get; private set; } 81 82 private DoubleWordRegisterCollection registers; 83 private PseudorandomNumberGenerator rng = EmulationManager.Instance.CurrentEmulation.RandomGenerator; 84 private IFlagRegisterField enable; 85 private IFlagRegisterField interruptEnable; 86 87 private enum Registers 88 { 89 Control = 0x0, 90 Status = 0x4, 91 Data = 0x8, 92 } 93 } 94 } 95