1 // 2 // Copyright (c) 2010-2024 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.Time; 9 using Antmicro.Renode.Core.Structure.Registers; 10 using Antmicro.Renode.Logging; 11 12 namespace Antmicro.Renode.Peripherals.Timers 13 { 14 // This peripheral implements an interface to Arm CoreSight SoC-400 timestamp generator module 15 public class RenesasRZG_SYC : BasicDoubleWordPeripheral, IKnownSize 16 { RenesasRZG_SYC(IMachine machine, long frequency)17 public RenesasRZG_SYC(IMachine machine, long frequency) : base(machine) 18 { 19 timer = new LimitTimer(machine.ClockSource, frequency, this, "Timestamp generator", ulong.MaxValue, Direction.Ascending, workMode: WorkMode.Periodic); 20 DefineRegisters(); 21 Reset(); 22 } 23 Reset()24 public override void Reset() 25 { 26 base.Reset(); 27 timer.Reset(); 28 timerValueLowerOverride = null; 29 } 30 31 public long Size => 0x10000; 32 DefineRegisters()33 private void DefineRegisters() 34 { 35 Registers.CounterControl.Define(this) 36 .WithFlag(0, name: "EN", 37 valueProviderCallback: _ => timer.Enabled, 38 writeCallback: (_, value) => timer.Enabled = value) 39 .WithTaggedFlag("HDBG", 1) 40 .WithReservedBits(2, 30); 41 42 Registers.CounterStatus.Define(this) 43 .WithReservedBits(0, 1) 44 .WithTaggedFlag("DBGH (Debug Halted)", 1) 45 .WithReservedBits(2, 30); 46 47 Registers.CounterValueLower.Define(this) 48 .WithValueField(0, 32, name: "CNTCVL_L_32", 49 valueProviderCallback: _ => timer.Value, 50 writeCallback: (_, value) => timerValueLowerOverride = (uint)value); 51 52 Registers.CounterValueUpper.Define(this) 53 .WithValueField(0, 32, name: "CNTCVU_U_32", 54 valueProviderCallback: _ => timer.Value >> 32, 55 writeCallback: (_, value) => 56 { 57 var newValue = (value << 32) | (timerValueLowerOverride ?? (uint)timer.Value); 58 timerValueLowerOverride = null; 59 60 if(!timer.Enabled) 61 { 62 this.WarningLog("Attempt to set the counter value to {0} while timer is running, ignoring", newValue); 63 return; 64 } 65 timer.Value = newValue; 66 }); 67 68 Registers.BaseFrequencyId.Define(this) 69 .WithValueField(0, 32, name: "FREQ", 70 valueProviderCallback: _ => (uint)timer.Frequency, 71 writeCallback: (_, value) => timer.Frequency = (long)value); 72 73 Registers.CounterValueLowerReadOnly.Define(this) 74 .WithValueField(0, 32, FieldMode.Read, name: "CNTCVL_L_32", 75 valueProviderCallback: _ => timer.Value); 76 77 Registers.CounterValueUpperReadOnly.Define(this) 78 .WithValueField(0, 32, FieldMode.Read, name: "CNTCVU_U_32", 79 valueProviderCallback: _ => timer.Value >> 32); 80 81 DefineManagementRegisters(0x0); 82 DefineManagementRegisters(0x1000); 83 } 84 DefineManagementRegisters(int offset)85 private void DefineManagementRegisters(int offset) 86 { 87 (ManagementRegisters.PeripheralID4 + offset).Define(this, 0x4) 88 .WithTag("DES_2", 0, 4) 89 .WithTag("SIZE", 4, 4) 90 .WithReservedBits(8, 24); 91 92 (ManagementRegisters.PeripheralID0 + offset).Define(this, 0x1) 93 .WithTag("PART_0", 0, 8) 94 .WithReservedBits(8, 24); 95 96 (ManagementRegisters.PeripheralID1 + offset).Define(this, 0xB1) 97 .WithTag("PART_1", 0, 4) 98 .WithTag("DES_0", 4, 4) 99 .WithReservedBits(8, 24); 100 101 (ManagementRegisters.PeripheralID2 + offset).Define(this, 0x1B) 102 .WithTag("DES_1", 0, 3) 103 .WithTaggedFlag("JEDEC", 3) 104 .WithTag("REVISION", 4, 4) 105 .WithReservedBits(8, 24); 106 107 (ManagementRegisters.PeripheralID3 + offset).Define(this, 0x0) 108 .WithTag("CMOD", 0, 4) 109 .WithTag("REVAND", 4, 4) 110 .WithReservedBits(8, 24); 111 112 (ManagementRegisters.ComponentID0 + offset).Define(this, 0xD) 113 .WithTag("PRMBL_0", 0, 8) 114 .WithReservedBits(8, 24); 115 116 (ManagementRegisters.ComponentID1 + offset).Define(this, 0xF0) 117 .WithTag("PRMBL_1", 0, 4) 118 .WithTag("CLASS", 4, 4) 119 .WithReservedBits(8, 24); 120 121 (ManagementRegisters.ComponentID2 + offset).Define(this, 0x5) 122 .WithTag("PRMBL_2", 0, 8) 123 .WithReservedBits(8, 24); 124 125 (ManagementRegisters.ComponentID3 + offset).Define(this, 0xB1) 126 .WithTag("PRMBL_3", 0, 8) 127 .WithReservedBits(8, 24); 128 } 129 130 private readonly LimitTimer timer; 131 // Nullable uint is used, so that software has the ability to only override 132 // the upper half of the counter's value 133 private uint? timerValueLowerOverride; 134 135 private enum Registers 136 { 137 CounterControl = 0x0000, // CNTCR 138 CounterStatus = 0x0004, // CNTSR 139 CounterValueLower = 0x0008, // CNTCVL 140 CounterValueUpper = 0x000C, // CNTCVU 141 BaseFrequencyId = 0x0020, // CNTFID0 142 CounterValueLowerReadOnly = 0x1000, // CNTCVL 143 CounterValueUpperReadOnly = 0x1004, // CNTCVU 144 } 145 146 private enum ManagementRegisters 147 { 148 PeripheralID4 = 0xFD0, // PIDR4 149 PeripheralID0 = 0xFE0, // PIDR0 150 PeripheralID1 = 0xFE4, // PIDR1 151 PeripheralID2 = 0xFE8, // PIDR2 152 PeripheralID3 = 0xFEC, // PIDR3 153 ComponentID0 = 0xFF0, // CIDR0 154 ComponentID1 = 0xFF4, // CIDR1 155 ComponentID2 = 0xFF8, // CIDR2 156 ComponentID3 = 0xFFC, // CIDR3 157 } 158 } 159 } 160