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.Collections.Generic; 8 using Antmicro.Renode.Peripherals.Bus; 9 using Antmicro.Renode.Core.Structure.Registers; 10 using Antmicro.Renode.Core; 11 using Antmicro.Renode.Time; 12 13 namespace Antmicro.Renode.Peripherals.Timers 14 { 15 public class Marvell_Armada_Timer : LimitTimer, IDoubleWordPeripheral, IKnownSize 16 { Marvell_Armada_Timer(IMachine machine, long frequency)17 public Marvell_Armada_Timer(IMachine machine, long frequency) : base(machine.ClockSource, frequency, direction: Direction.Descending, limit: uint.MaxValue, enabled: true) 18 { 19 var registersMap = new Dictionary<long, DoubleWordRegister> 20 { 21 {(long)Registers.Control, new DoubleWordRegister(this) 22 .WithTaggedFlag("Timer0En", 0) 23 .WithTaggedFlag("Timer0Auto", 1) 24 .WithTaggedFlag("Timer1En", 2) 25 .WithTaggedFlag("Timer1Auto", 3) 26 .WithTaggedFlag("Timer2En", 4) 27 .WithTaggedFlag("Timer2Auto", 5) 28 .WithTaggedFlag("Timer3En", 6) 29 .WithTaggedFlag("Timer3Auto", 7) 30 .WithTaggedFlag("WdTimerEn", 8) 31 .WithTaggedFlag("WdTimerAuto", 9) 32 .WithTaggedFlag("WdTimer25MhzEn", 10) 33 .WithTaggedFlag("Timer0_25MhzEn", 11) 34 .WithTaggedFlag("Timer1_25MhzEn", 12) 35 .WithTaggedFlag("Timer2_25MhzEn", 13) 36 .WithTaggedFlag("Timer3_25MhzEn", 14) 37 .WithReservedBits(15, 1) 38 .WithTag("WdTimerRatio", 16, 3) 39 .WithTag("Timer0Ratio", 19, 3) 40 .WithTag("Timer1Ratio", 22, 3) 41 .WithTag("Timer2Ratio", 25, 3) 42 .WithTag("Timer3Ratio", 28, 3) 43 .WithReservedBits(31, 1) 44 }, 45 {(long)Registers.EventStatus, new DoubleWordRegister(this) 46 .WithTaggedFlag("Timer0Expired", 0) 47 .WithReservedBits(1, 7) 48 .WithTaggedFlag("Timer1Expired", 8) 49 .WithReservedBits(9, 7) 50 .WithTaggedFlag("Timer2Expired", 16) 51 .WithReservedBits(17, 7) 52 .WithTaggedFlag("Timer3Expired", 24) 53 .WithReservedBits(25, 6) 54 .WithTaggedFlag("WdTimerExpired", 31) 55 }, 56 {(long)Registers.Timer0ReloadValue, new DoubleWordRegister(this) 57 .WithTag("Timer0Rel", 0, 32) 58 }, 59 {(long)Registers.Timer0Value, new DoubleWordRegister(this) 60 .WithValueField(0, 32, valueProviderCallback: _ => 61 { 62 if(machine.SystemBus.TryGetCurrentCPU(out var cpu)) 63 { 64 cpu.SyncTime(); 65 } 66 return (uint)Value; 67 }, writeCallback: (_, value) => Value = value) 68 }, 69 }; 70 registers = new DoubleWordRegisterCollection(this, registersMap); 71 } 72 ReadDoubleWord(long offset)73 public uint ReadDoubleWord(long offset) 74 { 75 return registers.Read(offset); 76 } 77 WriteDoubleWord(long offset, uint value)78 public void WriteDoubleWord(long offset, uint value) 79 { 80 registers.Write(offset, value); 81 } 82 Reset()83 public override void Reset() 84 { 85 base.Reset(); 86 registers.Reset(); 87 } 88 89 public long Size => 0x100; 90 91 private readonly DoubleWordRegisterCollection registers; 92 93 private enum Registers : long 94 { 95 Control = 0x00, 96 EventStatus = 0x04, 97 // gap 98 Timer0ReloadValue = 0x10, 99 Timer0Value = 0x14, 100 Timer1ReloadValue = 0x18, 101 Timer1Value = 0x1c, 102 Timer2ReloadValue = 0x20, 103 Timer2Value = 0x24, 104 Timer3ReloadValue = 0x28, 105 Timer3Value = 0x2c, 106 } 107 } 108 } 109