1 //
2 // Copyright (c) 2010-2025 Antmicro
3 //
4 // This file is licensed under the MIT License.
5 // Full license text is available in 'licenses/MIT.txt'.
6 //
7 
8 using System;
9 using Antmicro.Renode.Core.Structure.Registers;
10 using Antmicro.Renode.Utilities;
11 using Antmicro.Renode.Logging;
12 using Antmicro.Renode.Peripherals.Bus;
13 using Antmicro.Renode.Peripherals.CPU;
14 using System.Collections.Generic;
15 using Antmicro.Renode.Peripherals.Timers;
16 using Antmicro.Renode.Core.Structure;
17 using Antmicro.Renode.Exceptions;
18 
19 namespace Antmicro.Renode.Peripherals.Miscellaneous
20 {
21     public class RenesasRZG_CPG_SYSC : IDoubleWordPeripheral, IProvidesRegisterCollection<DoubleWordRegisterCollection>, IKnownSize, IPeripheralRegister<RenesasRZG_Watchdog, NumberRegistrationPoint<byte>>
22     {
RenesasRZG_CPG_SYSC(ICPU cpu0, ICPU cpu1 = null)23         public RenesasRZG_CPG_SYSC(ICPU cpu0, ICPU cpu1 = null)
24         {
25             this.cpu0 = cpu0;
26             this.cpu1 = cpu1;
27             RegistersCollection = new DoubleWordRegisterCollection(this, BuildRegisterMap());
28         }
29 
Reset()30         public void Reset()
31         {
32             RegistersCollection.Reset();
33         }
34 
ReadDoubleWord(long offset)35         public uint ReadDoubleWord(long offset)
36         {
37             return RegistersCollection.Read(offset);
38         }
39 
WriteDoubleWord(long offset, uint value)40         public void WriteDoubleWord(long offset, uint value)
41         {
42             RegistersCollection.Write(offset, value);
43         }
44 
Register(RenesasRZG_Watchdog wdt, NumberRegistrationPoint<byte> id)45         public void Register(RenesasRZG_Watchdog wdt, NumberRegistrationPoint<byte> id)
46         {
47             if(id.Address < 0 || id.Address >= MaxWatchdogCount)
48             {
49                 throw new RecoverableException($"{id.Address} is not a valid Watchdog ID");
50             }
51             if(watchdogs[id.Address] != null)
52             {
53                 throw new RecoverableException($"WDT{id.Address} is already connected");
54             }
55             var duplicateRegistration = watchdogs.IndexOf(x => x == wdt);
56             if(duplicateRegistration >= 0)
57             {
58                 throw new RecoverableException($"WDT{id.Address} is already connected as WDT{duplicateRegistration}");
59             }
60             watchdogs[id.Address] = wdt;
61         }
62 
Unregister(RenesasRZG_Watchdog wdt)63         public void Unregister(RenesasRZG_Watchdog wdt)
64         {
65             var i = watchdogs.IndexOf(x => x == wdt);
66             if(i >= 0)
67             {
68                 watchdogs[i] = null;
69             }
70         }
71 
72         public long Size => 0x20000;
73         public DoubleWordRegisterCollection RegistersCollection { get; }
74 
BuildRegisterMap()75         private Dictionary<long, DoubleWordRegister> BuildRegisterMap()
76         {
77             var registerMap = new Dictionary<long, DoubleWordRegister>();
78 
79             DefineCPGRegisters(registerMap);
80             DefineSYSCRegisters(registerMap);
81 
82             return registerMap;
83         }
84 
DefineSYSCRegisters(Dictionary<long, DoubleWordRegister> registerMap)85         private void DefineSYSCRegisters(Dictionary<long, DoubleWordRegister> registerMap)
86         {
87             registerMap.Add((long)Registers.MasterAccessControl0, new DoubleWordRegister(this, 0x00AAAA00)
88                 .WithTaggedFlag("DMAC0_AWPU", 0)
89                 .WithTaggedFlag("DMAC0_AWNS", 1)
90                 .WithReservedBits(2, 1)
91                 .WithTaggedFlag("DMAC0_AWSEL", 3)
92                 .WithTaggedFlag("DMAC0_ARRU", 4)
93                 .WithTaggedFlag("DMAC0_ARNS", 5)
94                 .WithReservedBits(6, 1)
95                 .WithTaggedFlag("DMAC0_ARSEL", 7)
96                 .WithTaggedFlag("DMAC1_AWPU", 8)
97                 .WithTaggedFlag("DMAC1_AWNS", 9)
98                 .WithReservedBits(10, 1)
99                 .WithTaggedFlag("DMAC1_AWSEL", 11)
100                 .WithTaggedFlag("DMAC1_ARRU", 12)
101                 .WithTaggedFlag("DMAC1_ARNS", 13)
102                 .WithReservedBits(14, 1)
103                 .WithTaggedFlag("DMAC1_ARSEL", 15)
104                 .WithTaggedFlag("GPU_AWPU", 16)
105                 .WithTaggedFlag("GPU_AWNS", 17)
106                 .WithReservedBits(18, 1)
107                 .WithTaggedFlag("GPU_AWSEL", 19)
108                 .WithTaggedFlag("GPU_ARRU", 20)
109                 .WithTaggedFlag("GPU_ARNS", 21)
110                 .WithReservedBits(22, 1)
111                 .WithTaggedFlag("GPU_ARSEL", 23)
112                 .WithReservedBits(24, 8)
113             );
114 
115             registerMap.Add((long)Registers.MasterAccessControl1, new DoubleWordRegister(this, 0x00AAAA00)
116                 .WithTaggedFlag("SDHI0_AWPU", 0)
117                 .WithTaggedFlag("SDHI0_AWNS", 1)
118                 .WithReservedBits(2, 1)
119                 .WithTaggedFlag("SDHI0_AWSEL", 3)
120                 .WithTaggedFlag("SDHI0_ARRU", 4)
121                 .WithTaggedFlag("SDHI0_ARNS", 5)
122                 .WithReservedBits(6, 1)
123                 .WithTaggedFlag("SDHI0_ARSEL", 7)
124                 .WithTaggedFlag("SDHI1_AWPU", 8)
125                 .WithTaggedFlag("SDHI1_AWNS", 9)
126                 .WithReservedBits(10, 1)
127                 .WithTaggedFlag("SDHI1_AWSEL", 11)
128                 .WithTaggedFlag("SDHI1_ARRU", 12)
129                 .WithTaggedFlag("SDHI1_ARNS", 13)
130                 .WithReservedBits(14, 1)
131                 .WithTaggedFlag("SDHI1_ARSEL", 15)
132                 .WithTaggedFlag("GEther0_AWPU", 16)
133                 .WithTaggedFlag("GEther0_AWNS", 17)
134                 .WithReservedBits(18, 1)
135                 .WithTaggedFlag("GEther0_AWSEL", 19)
136                 .WithTaggedFlag("GEther0_ARRU", 20)
137                 .WithTaggedFlag("GEther0_ARNS", 21)
138                 .WithReservedBits(22, 1)
139                 .WithTaggedFlag("GEther0_ARSEL", 23)
140                 .WithTaggedFlag("GEther1_AWPU", 24)
141                 .WithTaggedFlag("GEther1_AWNS", 25)
142                 .WithReservedBits(26, 1)
143                 .WithTaggedFlag("GEther1_AWSEL", 27)
144                 .WithTaggedFlag("GEther1_ARRU", 28)
145                 .WithTaggedFlag("GEther1_ARNS", 29)
146                 .WithReservedBits(30, 1)
147                 .WithTaggedFlag("GEther1_ARSEL", 31)
148             );
149 
150             registerMap.Add((long)Registers.MasterAccessControl2, new DoubleWordRegister(this, 0x00AAAA00)
151                 .WithTaggedFlag("USB2_0H_AWPU", 0)
152                 .WithTaggedFlag("USB2_0H_AWNS", 1)
153                 .WithReservedBits(2, 1)
154                 .WithTaggedFlag("USB2_0H_AWSEL", 3)
155                 .WithTaggedFlag("USB2_0H_ARRU", 4)
156                 .WithTaggedFlag("USB2_0H_ARNS", 5)
157                 .WithReservedBits(6, 1)
158                 .WithTaggedFlag("USB2_0H_ARSEL", 7)
159                 .WithTaggedFlag("USB2_1H_AWPU", 8)
160                 .WithTaggedFlag("USB2_1H_AWNS", 9)
161                 .WithReservedBits(10, 1)
162                 .WithTaggedFlag("USB2_1H_AWSEL", 11)
163                 .WithTaggedFlag("USB2_1H_ARRU", 12)
164                 .WithTaggedFlag("USB2_1H_ARNS", 13)
165                 .WithReservedBits(14, 1)
166                 .WithTaggedFlag("USB2_1H_ARSEL", 15)
167                 .WithTaggedFlag("USB2_0D_AWPU", 16)
168                 .WithTaggedFlag("USB2_0D_AWNS", 17)
169                 .WithReservedBits(18, 1)
170                 .WithTaggedFlag("USB2_0D_AWSEL", 19)
171                 .WithTaggedFlag("USB2_0D_ARRU", 20)
172                 .WithTaggedFlag("USB2_0D_ARNS", 21)
173                 .WithReservedBits(22, 1)
174                 .WithTaggedFlag("USB2_0D_ARSEL", 23)
175                 .WithReservedBits(24, 8)
176             );
177 
178             registerMap.Add((long)Registers.MasterAccessControl3, new DoubleWordRegister(this, 0x00AAAA00)
179                 .WithTaggedFlag("H264_AWPU", 0)
180                 .WithTaggedFlag("H264_AWNS", 1)
181                 .WithReservedBits(2, 1)
182                 .WithTaggedFlag("H264_AWSEL", 3)
183                 .WithTaggedFlag("H264_ARRU", 4)
184                 .WithTaggedFlag("H264_ARNS", 5)
185                 .WithReservedBits(6, 1)
186                 .WithTaggedFlag("H264_ARSEL", 7)
187                 .WithTaggedFlag("LCDC_AWPU", 8)
188                 .WithTaggedFlag("LCDC_AWNS", 9)
189                 .WithReservedBits(10, 1)
190                 .WithTaggedFlag("LCDC_AWSEL", 11)
191                 .WithTaggedFlag("LCDC_ARRU", 12)
192                 .WithTaggedFlag("LCDC_ARNS", 13)
193                 .WithReservedBits(14, 1)
194                 .WithTaggedFlag("LCDC_ARSEL", 15)
195                 .WithTaggedFlag("DSI_AWPU", 16)
196                 .WithTaggedFlag("DSI_AWNS", 17)
197                 .WithReservedBits(18, 1)
198                 .WithTaggedFlag("DSI_AWSEL", 19)
199                 .WithTaggedFlag("DSI_ARRU", 20)
200                 .WithTaggedFlag("DSI_ARNS", 21)
201                 .WithReservedBits(22, 1)
202                 .WithTaggedFlag("DSI_ARSEL", 23)
203                 .WithReservedBits(24, 8)
204             );
205 
206             registerMap.Add((long)Registers.MasterAccessControl4, new DoubleWordRegister(this, 0xAAAA00AA)
207                 .WithTaggedFlag("ISU_AWPU", 0)
208                 .WithTaggedFlag("ISU_AWNS", 1)
209                 .WithReservedBits(2, 1)
210                 .WithTaggedFlag("ISU_AWSEL", 3)
211                 .WithTaggedFlag("ISU_ARRU", 4)
212                 .WithTaggedFlag("ISU_ARNS", 5)
213                 .WithReservedBits(6, 1)
214                 .WithTaggedFlag("ISU_ARSEL", 7)
215                 .WithReservedBits(8, 8)
216                 .WithTaggedFlag("CRU_VD_AWPU", 16)
217                 .WithTaggedFlag("CRU_VD_AWNS", 17)
218                 .WithReservedBits(18, 1)
219                 .WithTaggedFlag("CRU_VD_AWSEL", 19)
220                 .WithReservedBits(20, 4)
221                 .WithTaggedFlag("CRU_ST_AWPU", 24)
222                 .WithTaggedFlag("CRU_ST_AWNS", 25)
223                 .WithReservedBits(26, 1)
224                 .WithTaggedFlag("CRU_ST_AWSEL", 27)
225                 .WithReservedBits(28, 4)
226             );
227 
228             registerMap.Add((long)Registers.SlaveAccessControl0, new DoubleWordRegister(this, 0x0AAAAAA0)
229                 .WithTag("SRAM0_SL", 0, 2)
230                 .WithTag("SRAM1_SL", 2, 2)
231                 .WithReservedBits(4, 28)
232             );
233 
234             registerMap.Add((long)Registers.SlaveAccessControl1, new DoubleWordRegister(this, 0x0800C0AA)
235                 .WithTag("TZC0_SL", 0, 2)
236                 .WithTag("TZC1_SL", 2, 2)
237                 .WithTag("TZC2_SL", 4, 2)
238                 .WithTag("TZC3_SL", 6, 2)
239                 .WithReservedBits(8, 2)
240                 .WithTag("CST_SL", 10, 2)
241                 .WithTag("CPG_SL", 12, 2)
242                 .WithTag("SYSC_SL", 14, 2)
243                 .WithTag("SYS_SL", 16, 2)
244                 .WithTag("GIC_SL", 18, 2)
245                 .WithTag("IA55_IM33_SL", 20, 2)
246                 .WithTag("GPIO_SL", 22, 2)
247                 .WithTag("MHU_SL", 24, 2)
248                 .WithTag("DMAC0_SL", 26, 2)
249                 .WithTag("DMAC1_SL", 28, 2)
250                 .WithReservedBits(30, 2)
251             );
252 
253             registerMap.Add((long)Registers.SlaveAccessControl2, new DoubleWordRegister(this, 0x00000002)
254                 .WithTag("OSTM0_SL", 0, 2)
255                 .WithTag("OSTM1_SL", 2, 2)
256                 .WithTag("OSTM2_SL", 4, 2)
257                 .WithTag("WDT0_SL", 6, 2)
258                 .WithTag("WDT1_SL", 8, 2)
259                 .WithTag("WDT2_SL", 10, 2)
260                 .WithReservedBits(12, 2)
261                 .WithTag("MTU3A_SL", 14, 2)
262                 .WithTag("POE3_SL", 16, 2)
263                 .WithTag("GPT_SL", 18, 2)
264                 .WithTag("POEG_SL", 20, 2)
265                 .WithTag("DDR_SL", 22, 2)
266                 .WithReservedBits(24, 8)
267             );
268 
269             registerMap.Add((long)Registers.SlaveAccessControl3, new DoubleWordRegister(this)
270                 .WithTag("GPU_SL", 0, 2)
271                 .WithTag("H264_SL", 2, 2)
272                 .WithTag("CRU_SL", 4, 2)
273                 .WithTag("ISU_SL", 6, 2)
274                 .WithTag("DSIPHY_SL", 8, 2)
275                 .WithTag("DSILINK_SL", 10, 2)
276                 .WithTag("LCDC_SL", 12, 2)
277                 .WithReservedBits(14, 2)
278                 .WithTag("USBT_SL", 16, 2)
279                 .WithTag("USB20_SL", 18, 2)
280                 .WithTag("USB21_SL", 20, 2)
281                 .WithTag("SDHI0_SL", 22, 2)
282                 .WithTag("SDHI1_SL", 24, 2)
283                 .WithTag("ETH0_SL", 26, 2)
284                 .WithTag("ETH1_SL", 28, 2)
285                 .WithReservedBits(30, 2)
286             );
287 
288             registerMap.Add((long)Registers.SlaveAccessControl4, new DoubleWordRegister(this)
289                 .WithTag("I2C0_SL", 0, 2)
290                 .WithTag("I2C1_SL", 2, 2)
291                 .WithTag("I2C2_SL", 4, 2)
292                 .WithTag("I2C3_SL", 6, 2)
293                 .WithTag("CANFD_SL", 8, 2)
294                 .WithTag("RSPI_SL", 10, 2)
295                 .WithReservedBits(12, 4)
296                 .WithTag("SCIF0_SL", 16, 2)
297                 .WithTag("SCIF1_SL", 18, 2)
298                 .WithTag("SCIF2_SL", 20, 2)
299                 .WithTag("SCIF3_SL", 22, 2)
300                 .WithTag("SCIF4_SL", 24, 2)
301                 .WithTag("SCI0_SL", 26, 2)
302                 .WithTag("SCI1_SL", 28, 2)
303                 .WithTag("IRDA_SL", 30, 2)
304             );
305 
306             registerMap.Add((long)Registers.SlaveAccessControl5, new DoubleWordRegister(this)
307                 .WithTag("SSIF_SL", 0, 2)
308                 .WithReservedBits(2, 2)
309                 .WithTag("SRC_SL", 4, 2)
310                 .WithReservedBits(6, 26)
311             );
312 
313             registerMap.Add((long)Registers.SlaveAccessControl6, new DoubleWordRegister(this)
314                 .WithTag("ADC_SL", 0, 2)
315                 .WithTag("TSU_SL", 2, 2)
316                 .WithReservedBits(4, 28)
317             );
318 
319             registerMap.Add((long)Registers.SlaveAccessControl7, new DoubleWordRegister(this)
320                 .WithReservedBits(0, 2)
321                 .WithTag("OTP_SL", 2, 2)
322                 .WithReservedBits(4, 28)
323             );
324 
325             registerMap.Add((long)Registers.SlaveAccessControl8, new DoubleWordRegister(this)
326                 .WithTag("CM33_SL", 0, 2)
327                 .WithTag("CA55_SL", 2, 2)
328                 .WithReservedBits(4, 28)
329             );
330 
331             registerMap.Add((long)Registers.SlaveAccessControl10, new DoubleWordRegister(this)
332                 .WithTag("LSI_SL", 0, 2)
333                 .WithReservedBits(2, 30)
334             );
335 
336             registerMap.Add((long)Registers.SlaveAccessControl12, new DoubleWordRegister(this)
337                 .WithTag("AOF_SL", 0, 2)
338                 .WithReservedBits(2, 30)
339             );
340 
341             registerMap.Add((long)Registers.SlaveAccessControl13, new DoubleWordRegister(this)
342                 .WithTag("LP_SL", 0, 2)
343                 .WithReservedBits(2, 30)
344             );
345 
346             registerMap.Add((long)Registers.SlaveAccessControl14, new DoubleWordRegister(this)
347                 .WithTag("GPREG_SL", 0, 2)
348                 .WithReservedBits(2, 30)
349             );
350 
351             registerMap.Add((long)Registers.ErrorCorrectingCodeRam0Settings, new DoubleWordRegister(this)
352                 .WithTaggedFlag("VECCEN", 0)
353                 .WithReservedBits(1, 31)
354             );
355 
356             registerMap.Add((long)Registers.ErrorCorrectingCodeRam0AccessControl, new DoubleWordRegister(this, 0x00000003)
357                 .WithTaggedFlag("VCEN", 0)
358                 .WithTaggedFlag("VLWEN", 1)
359                 .WithReservedBits(2, 30)
360             );
361 
362             registerMap.Add((long)Registers.ErrorCorrectingCodeRam1Settings, new DoubleWordRegister(this)
363                 .WithTaggedFlag("VECCEN", 0)
364                 .WithReservedBits(1, 31)
365             );
366 
367             registerMap.Add((long)Registers.ErrorCorrectingCodeRam1AccessControl, new DoubleWordRegister(this, 0x00000003)
368                 .WithTaggedFlag("VCEN", 0)
369                 .WithTaggedFlag("VLWEN", 1)
370                 .WithReservedBits(2, 30)
371             );
372 
373             registerMap.Add((long)Registers.WatchdogTimer0Control, CreateWatchdogTimerControlRegister(0));
374 
375             registerMap.Add((long)Registers.WatchdogTimer1Control, CreateWatchdogTimerControlRegister(1));
376 
377             registerMap.Add((long)Registers.WatchdogTimer2Control, CreateWatchdogTimerControlRegister(2));
378 
379             registerMap.Add((long)Registers.GigabitEthernet0Config, new DoubleWordRegister(this)
380                 .WithReservedBits(0, 24)
381                 .WithTaggedFlag("FEC_GIGA_ENABLE", 24)
382                 .WithReservedBits(25, 7)
383             );
384 
385             registerMap.Add((long)Registers.GigabitEthernet1Config, new DoubleWordRegister(this)
386                 .WithReservedBits(0, 24)
387                 .WithTaggedFlag("FEC_GIGA_ENABLE", 24)
388                 .WithReservedBits(25, 7)
389             );
390 
391             registerMap.Add((long)Registers.I2c0Config, new DoubleWordRegister(this)
392                 .WithTaggedFlag("AF_BYPASS", 0)
393                 .WithReservedBits(1, 31)
394             );
395 
396             registerMap.Add((long)Registers.I2c1Config, new DoubleWordRegister(this)
397                 .WithTaggedFlag("AF_BYPASS", 0)
398                 .WithReservedBits(1, 31)
399             );
400 
401             registerMap.Add((long)Registers.I2c2Config, new DoubleWordRegister(this)
402                 .WithTaggedFlag("AF_BYPASS", 0)
403                 .WithReservedBits(1, 31)
404             );
405 
406             registerMap.Add((long)Registers.I2c3Config, new DoubleWordRegister(this)
407                 .WithTaggedFlag("AF_BYPASS", 0)
408                 .WithReservedBits(1, 31)
409             );
410 
411             registerMap.Add((long)Registers.CortexM33Config0, new DoubleWordRegister(this, 0x00003D08)
412                 .WithTag("CONFIGSSYSTICK", 0, 26)
413                 .WithReservedBits(26, 6)
414             );
415 
416             registerMap.Add((long)Registers.CortexM33Config1, new DoubleWordRegister(this, 0x00003D08)
417                 .WithTag("CONFIGNSSYSTICK", 0, 26)
418                 .WithReservedBits(26, 6)
419             );
420 
421             registerMap.Add((long)Registers.CortexM33Config2, new DoubleWordRegister(this, 0x10010000)
422                 .WithReservedBits(0, 7)
423                 .WithTag("INITSVTOR", 7, 25)
424             );
425 
426             registerMap.Add((long)Registers.CortexM33Config3, new DoubleWordRegister(this, 0x10018000)
427                 .WithReservedBits(0, 7)
428                 .WithTag("INITNSVTOR", 7, 25)
429             );
430 
431             registerMap.Add((long)Registers.CortexM33Lock, new DoubleWordRegister(this)
432                 .WithTaggedFlag("LOCKSVTAIRCR", 0)
433                 .WithTaggedFlag("LOCKNSVTOR", 1)
434                 .WithReservedBits(2, 30)
435             );
436 
437             registerMap.Add((long)Registers.CortexA55Core0ResetVectorAddressLowConfig, new DoubleWordRegister(this)
438                 .WithReservedBits(0, 2)
439                 .WithTag("RVBARADDRL0", 2, 30)
440             );
441 
442             registerMap.Add((long)Registers.CortexA55Core0ResetVectorAddressHighConfig, new DoubleWordRegister(this)
443                 .WithTag("RVBARADDRH0", 0, 8)
444                 .WithReservedBits(8, 24)
445             );
446 
447             registerMap.Add((long)Registers.CortexA55Core1ResetVectorAddressLowConfig, new DoubleWordRegister(this, 0x00020000)
448                 .WithReservedBits(0, 2)
449                 .WithValueField(2, 30, out cortexA55Core1ResetVectorLow, name: "RVBARADDRL1")
450             );
451 
452             registerMap.Add((long)Registers.CortexA55Core1ResetVectorAddressHighConfig, new DoubleWordRegister(this)
453                 .WithValueField(0, 8, out cortexA55Core1ResetVectorHigh, name: "RVBARADDRH1")
454                 .WithReservedBits(8, 24)
455             );
456 
457             registerMap.Add((long)Registers.LsiModeSignal, new DoubleWordRegister(this)
458                 .WithTag("STAT_MD_BOOT", 0, 3)
459                 .WithReservedBits(3, 6)
460                 .WithTaggedFlag("STAT_DEBUGEN", 9)
461                 .WithReservedBits(10, 2)
462                 .WithTaggedFlag("STAT_MD_CLKS", 12)
463                 .WithReservedBits(13, 1)
464                 .WithTag("STAT_MD_OSCDRV", 14, 2)
465                 .WithTaggedFlag("STAT_SEC_EN", 16)
466                 .WithReservedBits(17, 15)
467             );
468 
469             registerMap.Add((long)Registers.LsiDeviceId, new DoubleWordRegister(this, 0x0841C447)
470                 .WithValueField(0, 32, FieldMode.Read, name: "DEV_ID")
471             );
472 
473             registerMap.Add((long)Registers.LsiProduct, new DoubleWordRegister(this, (uint)(HasTwoCortexA55Cores ? 0x0 : 0x1))
474                 .WithFlag(0, FieldMode.Read, name: "CA55_1CPU")
475                 .WithReservedBits(1, 31)
476             );
477 
478             registerMap.Add((long)Registers.AddressOffset0, new DoubleWordRegister(this, 0x32103210)
479                 .WithTag("OFS00_SXSDHI_0", 0, 4)
480                 .WithTag("OFS01_SXSDHI_0", 4, 4)
481                 .WithTag("OFS10_SXSDHI_0", 8, 4)
482                 .WithTag("OFS11_SXSDHI_0", 12, 4)
483                 .WithTag("OFS00_SXSDHI_1", 16, 4)
484                 .WithTag("OFS01_SXSDHI_1", 20, 4)
485                 .WithTag("OFS10_SXSDHI_1", 24, 4)
486                 .WithTag("OFS11_SXSDHI_1", 28, 4)
487             );
488 
489             registerMap.Add((long)Registers.AddressOffset1, new DoubleWordRegister(this, 0x32103210)
490                 .WithTag("OFS00_SXGIGE_0", 0, 4)
491                 .WithTag("OFS01_SXGIGE_0", 4, 4)
492                 .WithTag("OFS10_SXGIGE_0", 8, 4)
493                 .WithTag("OFS11_SXGIGE_0", 12, 4)
494                 .WithTag("OFS00_SXGIGE_1", 16, 4)
495                 .WithTag("OFS01_SXGIGE_1", 20, 4)
496                 .WithTag("OFS10_SXGIGE_1", 24, 4)
497                 .WithTag("OFS11_SXGIGE_1", 28, 4)
498             );
499 
500             registerMap.Add((long)Registers.AddressOffset2, new DoubleWordRegister(this, 0x32103210)
501                 .WithTag("OFS00_SXUSB2_0_H", 0, 4)
502                 .WithTag("OFS01_SXUSB2_0_H", 4, 4)
503                 .WithTag("OFS10_SXUSB2_0_H", 8, 4)
504                 .WithTag("OFS11_SXUSB2_0_H", 12, 4)
505                 .WithTag("OFS00_SXUSB2_1", 16, 4)
506                 .WithTag("OFS01_SXUSB2_1", 20, 4)
507                 .WithTag("OFS10_SXUSB2_1", 24, 4)
508                 .WithTag("OFS11_SXUSB2_1", 28, 4)
509             );
510 
511             registerMap.Add((long)Registers.AddressOffset3, new DoubleWordRegister(this, 0x00003210)
512                 .WithTag("OFS00_SXUSB2_0_F", 0, 4)
513                 .WithTag("OFS01_SXUSB2_0_F", 4, 4)
514                 .WithTag("OFS10_SXUSB2_0_F", 8, 4)
515                 .WithTag("OFS11_SXUSB2_0_F", 12, 4)
516                 .WithReservedBits(16, 16)
517             );
518 
519             registerMap.Add((long)Registers.AddressOffset4, new DoubleWordRegister(this, 0x32103210)
520                 .WithTag("OFS00_SXLCDC", 0, 4)
521                 .WithTag("OFS01_SXLCDC", 4, 4)
522                 .WithTag("OFS10_SXLCDC", 8, 4)
523                 .WithTag("OFS11_SXLCDC", 12, 4)
524                 .WithTag("OFS00_SXDSIL", 16, 4)
525                 .WithTag("OFS01_SXDSIL", 20, 4)
526                 .WithTag("OFS10_SXDSIL", 24, 4)
527                 .WithTag("OFS11_SXDSIL", 28, 4)
528             );
529 
530             registerMap.Add((long)Registers.AddressOffset5, new DoubleWordRegister(this, 0x00003210)
531                 .WithTag("OFS00_SXH264", 0, 4)
532                 .WithTag("OFS01_SXH264", 4, 4)
533                 .WithTag("OFS10_SXH264", 8, 4)
534                 .WithTag("OFS11_SXH264", 12, 4)
535                 .WithReservedBits(16, 16)
536             );
537 
538             registerMap.Add((long)Registers.AddressOffset6, new DoubleWordRegister(this, 0x32103210)
539                 .WithTag("OFS00_SXDMAC_S", 0, 4)
540                 .WithTag("OFS01_SXDMAC_S", 4, 4)
541                 .WithTag("OFS10_SXDMAC_S", 8, 4)
542                 .WithTag("OFS11_SXDMAC_S", 12, 4)
543                 .WithTag("OFS00_SXDMAC_NS", 16, 4)
544                 .WithTag("OFS01_SXDMAC_NS", 20, 4)
545                 .WithTag("OFS10_SXDMAC_NS", 24, 4)
546                 .WithTag("OFS11_SXDMAC_NS", 28, 4)
547             );
548 
549             registerMap.Add((long)Registers.LowPowerSequenceControl1, new DoubleWordRegister(this)
550                 .WithReservedBits(0, 8)
551                 .WithTag("CA55SLEEP_REQ", 8, 2)
552                 .WithReservedBits(10, 2)
553                 .WithTaggedFlag("CM33SLEEP_REQ", 12)
554                 .WithReservedBits(13, 11)
555                 .WithTag("CA55SLEEP_ACK", 24, 2)
556                 .WithReservedBits(26, 2)
557                 .WithTaggedFlag("CM33SLEEP_ACK", 28)
558                 .WithReservedBits(29, 3)
559             );
560 
561             registerMap.Add((long)Registers.LowPowerSequenceControl2, new DoubleWordRegister(this)
562                 .WithTaggedFlag("CA55_STBYCTL", 0)
563                 .WithReservedBits(1, 31)
564             );
565 
566             registerMap.Add((long)Registers.LowPowerSequenceControl5, new DoubleWordRegister(this)
567                 .WithReservedBits(0, 1)
568                 .WithTaggedFlag("ASCLKQDENY_F", 1)
569                 .WithTaggedFlag("AMCLKQDENY_F", 2)
570                 .WithReservedBits(3, 5)
571                 .WithTaggedFlag("CA55SLEEP1_F", 8)
572                 .WithTaggedFlag("CA55SLEEP1_F", 9)
573                 .WithTaggedFlag("CM33SLEEP_F", 10)
574                 .WithReservedBits(11, 21)
575             );
576 
577             registerMap.Add((long)Registers.LowPowerSequenceControl6, new DoubleWordRegister(this)
578                 .WithReservedBits(0, 1)
579                 .WithTaggedFlag("ASCLKQDENY_E", 1)
580                 .WithTaggedFlag("AMCLKQDENY_E", 2)
581                 .WithReservedBits(3, 5)
582                 .WithTaggedFlag("CA55SLEEP1_E", 8)
583                 .WithTaggedFlag("CA55SLEEP1_E", 9)
584                 .WithTaggedFlag("CM33SLEEP_E", 10)
585                 .WithReservedBits(11, 21)
586             );
587 
588             registerMap.Add((long)Registers.LowPowerSequenceControl7, new DoubleWordRegister(this)
589                 .WithTaggedFlag("IM33_MASK", 0)
590                 .WithReservedBits(1, 31)
591             );
592 
593             registerMap.Add((long)Registers.LowPowerSequenceCortexM33Control0, new DoubleWordRegister(this)
594                 .WithTaggedFlag("SLEEPMODE", 0)
595                 .WithReservedBits(1, 3)
596                 .WithTaggedFlag("SLEEPDEEP", 4)
597                 .WithReservedBits(5, 4)
598                 .WithTaggedFlag("SYSRESETREQ", 9)
599                 .WithReservedBits(10, 22)
600             );
601 
602             registerMap.Add((long)Registers.CortexA55ClockControl1, new DoubleWordRegister(this)
603                 .WithReservedBits(0, 1)
604                 .WithTaggedFlag("ASCLKQACTIVE", 1)
605                 .WithTaggedFlag("AMCLKQACTIVE", 2)
606                 .WithReservedBits(3, 5)
607                 .WithTaggedFlag("PCLKQACTIVE", 8)
608                 .WithTaggedFlag("ATCLKQACTIVE", 9)
609                 .WithTaggedFlag("GICCLKQACTIVE", 10)
610                 .WithTaggedFlag("PDBGCLKQACTIVE", 11)
611                 .WithReservedBits(12, 20)
612             );
613 
614             registerMap.Add((long)Registers.CortexA55ClockControl2, new DoubleWordRegister(this, 0x00000F06)
615                 .WithReservedBits(0, 1)
616                 .WithTaggedFlag("ASCLKQREQn", 1)
617                 .WithTaggedFlag("AMCLKQREQn", 2)
618                 .WithReservedBits(3, 5)
619                 .WithTaggedFlag("PCLKQREQn", 8)
620                 .WithTaggedFlag("ATCLKQREQn", 9)
621                 .WithTaggedFlag("GICCLKQREQn", 10)
622                 .WithTaggedFlag("PDBGCLKQREQn", 11)
623                 .WithReservedBits(12, 20)
624             );
625 
626             registerMap.Add((long)Registers.CortexA55ClockControl3, new DoubleWordRegister(this)
627                 .WithTaggedFlag("CA55_COREINSTRRUN[0]", 0)
628                 .WithTaggedFlag("ASCLKQACCEPTn", 1)
629                 .WithTaggedFlag("AMCLKQACCEPTn", 2)
630                 .WithReservedBits(3, 5)
631                 .WithTaggedFlag("PCLKQACCEPTn", 8)
632                 .WithTaggedFlag("ATCLKQACCEPTn", 9)
633                 .WithTaggedFlag("GICCLKQAACCEPTn", 10)
634                 .WithTaggedFlag("PDBGCLKQACCEPTn", 11)
635                 .WithReservedBits(12, 4)
636                 .WithTaggedFlag("CA55_COREINSTRRUN[1]", 16)
637                 .WithTaggedFlag("ASCLKQDENY", 17)
638                 .WithTaggedFlag("AMCLKQDENY", 18)
639                 .WithReservedBits(19, 5)
640                 .WithTaggedFlag("PCLKQDENY", 24)
641                 .WithTaggedFlag("ATCLKQDENY", 25)
642                 .WithTaggedFlag("GICCLKQADENY", 26)
643                 .WithTaggedFlag("PDBGCLKQDENY", 27)
644                 .WithReservedBits(28, 4)
645             );
646 
647             registerMap.Add((long)Registers.GpuLowPowerSequenceControl, new DoubleWordRegister(this, 0x00001F00)
648                 .WithTaggedFlag("QACTIVE_GPU", 0)
649                 .WithTaggedFlag("QACTIVE_AXI_SLV", 1)
650                 .WithTaggedFlag("QACTIVE_AXI_MST", 2)
651                 .WithTaggedFlag("QACTIVE_ACE_SLV", 3)
652                 .WithTaggedFlag("QACTIVE_ACE_MST", 4)
653                 .WithReservedBits(5, 3)
654                 .WithTaggedFlag("QREQn_GPU", 8)
655                 .WithTaggedFlag("QREQn_AXI_SLV", 9)
656                 .WithTaggedFlag("QREQn_AXI_MST", 10)
657                 .WithTaggedFlag("QREQn_ACE_SLV", 11)
658                 .WithTaggedFlag("QREQn_ACE_MST", 12)
659                 .WithReservedBits(13, 3)
660                 .WithTaggedFlag("QACCEPTn_GPU", 16)
661                 .WithTaggedFlag("QACCEPTn_AXI_SLV", 17)
662                 .WithTaggedFlag("QACCEPTn_AXI_MST", 18)
663                 .WithTaggedFlag("QACCEPTn_ACE_SLV", 19)
664                 .WithTaggedFlag("QACCEPTn_ACE_MST", 20)
665                 .WithReservedBits(21, 3)
666                 .WithTaggedFlag("QDENY_GPU", 24)
667                 .WithTaggedFlag("QDENY_AXI_SLV", 25)
668                 .WithTaggedFlag("QDENY_AXI_MST", 26)
669                 .WithTaggedFlag("QDENY_ACE_SLV", 27)
670                 .WithTaggedFlag("QDENY_ACE_MST", 28)
671                 .WithReservedBits(29, 3)
672             );
673 
674             registerMap.Add((long)Registers.General0, new DoubleWordRegister(this)
675                 .WithValueField(0, 32, name: "GPREG0")
676             );
677 
678             registerMap.Add((long)Registers.General1, new DoubleWordRegister(this)
679                 .WithValueField(0, 32, name: "GPREG1")
680             );
681 
682             registerMap.Add((long)Registers.General2, new DoubleWordRegister(this)
683                 .WithValueField(0, 32, name: "GPREG2")
684             );
685 
686             registerMap.Add((long)Registers.General3, new DoubleWordRegister(this)
687                 .WithValueField(0, 32, name: "GPREG3")
688             );
689         }
690 
DefineCPGRegisters(Dictionary<long, DoubleWordRegister> registerMap)691         private void DefineCPGRegisters(Dictionary<long, DoubleWordRegister> registerMap)
692         {
693             var canClearWatchdogReset = new bool[MaxWatchdogCount];
694             registerMap.Add((long)Registers.WDTOverflowSystemReset, new DoubleWordRegister(this)
695                 .WithFlags(0, MaxWatchdogCount, FieldMode.WriteOneToClear | FieldMode.Read, name: "WDTOVF",
696                     valueProviderCallback: (idx, _) => watchdogs[idx]?.GeneratedReset ?? false,
697                     writeCallback: (idx, _, val) =>
698                     {
699                         if(!canClearWatchdogReset[idx])
700                         {
701                             this.WarningLog("WDT reset clearing is disabled for WDT{0}. Ignoring", idx);
702                             return;
703                         }
704 
705                         if(val && watchdogs[idx] != null)
706                         {
707                             watchdogs[idx].GeneratedReset = false;
708                         }
709                     }
710                 )
711                 .WithReservedBits(MaxWatchdogCount, 16 - MaxWatchdogCount)
712                 .WithFlags(16, MaxWatchdogCount, name: "WDTOVF_EN",
713                     valueProviderCallback: (_, __) => false,
714                     writeCallback: (idx, _, val) =>
715                     {
716                         if(val)
717                         {
718                             canClearWatchdogReset[idx] = val;
719                         }
720                     })
721             );
722 
723             registerMap.Add((long)Registers.WDTResetSelector, new DoubleWordRegister(this, 0x88)
724                 .WithFlags(0, MaxWatchdogCount, name: "WDTRSTSEL",
725                     valueProviderCallback: (idx, _) => watchdogs[idx]?.SystemResetEnabled ?? false,
726                     writeCallback: (idx, _, val) =>
727                     {
728                         this.DebugLog("System reset for WDT{0}: {1}", idx, val ? "enabled" : "disabled");
729                         if(watchdogs[idx] != null)
730                         {
731                             watchdogs[idx].SystemResetEnabled = val;
732                         }
733                     }
734                 )
735                 .WithReservedBits(3, 1)
736                 .WithTaggedFlags("WDTRSTSEL", 4, 3)
737                 .WithReservedBits(7, 1)
738                 .WithTaggedFlags("WDTRSTSEL", 8, 3)
739                 .WithReservedBits(11, 21)
740             );
741 
742             registerMap.Add((long)Registers.CortexA55Core1PowerStatusMonitor, new DoubleWordRegister(this)
743                 .WithFlag(0, FieldMode.Read,
744                     valueProviderCallback: _ =>
745                     {
746                         var retVal = cortexA55Core1PowerTransitionReq.Value;
747                         cortexA55Core1PowerTransitionReq.Value = false;
748                         return retVal;
749                     },
750                     name: "PACCEPT1_MON")
751                 .WithFlag(1, FieldMode.Read,
752                     valueProviderCallback: _ => false,
753                     name: "PDENY1_MON")
754                 .WithReservedBits(2, 30)
755             );
756 
757             registerMap.Add((long)Registers.CortexA55Core1PowerStatusControl, new DoubleWordRegister(this)
758                 .WithFlag(0, out cortexA55Core1PowerTransitionReq, name: "PREQ1_SET")
759                 .WithReservedBits(1, 15)
760                 .WithEnumField(16, 6, out cortexA55Core1PowerTransitionState, name:"PSTATE1_SET")
761                 .WithReservedBits(22, 10)
762                 .WithWriteCallback((_, __) =>
763                 {
764                     if(!cortexA55Core1PowerTransitionReq.Value)
765                     {
766                         return;
767                     }
768 
769                     if(!HasTwoCortexA55Cores)
770                     {
771                         this.WarningLog("Trying to change power state of cpu1, but platform has only cpu0.");
772                         return;
773                     }
774                     switch(cortexA55Core1PowerTransitionState.Value)
775                     {
776                         case PowerTransitionState.Off:
777                         case PowerTransitionState.OffEmulated:
778                             cpu1.IsHalted = true;
779                             this.DebugLog("Stopping CPU1");
780                             break;
781                         case PowerTransitionState.On:
782                             cpu1.PC = CortexA55Core1ResetVector;
783                             cpu1.IsHalted = false;
784                             this.DebugLog("Starting CPU1 at 0x{0:X}", CortexA55Core1ResetVector);
785                             break;
786                         default:
787                             this.WarningLog(
788                                 "Trying to trigger power state transition of cpu1 to invalid state 0x{0:X}",
789                                 cortexA55Core1PowerTransitionState.Value
790                             );
791                             break;
792                     }
793                 })
794             );
795 
796             DefineRegistersForPeripheral(registerMap, Registers.ClockControlCA55, Registers.ClockMonitorCA55,
797                 Registers.ResetControlCA55, Registers.ResetMonitorCA55, NrOfCa55Clocks);
798 
799             DefineRegistersForPeripheral(registerMap, Registers.ClockControlGIC, Registers.ClockMonitorGIC,
800                 Registers.ResetControlGIC, Registers.ResetMonitorGIC, NrOfGicClocks);
801 
802             DefineRegistersForPeripheral(registerMap, Registers.ClockControlIA55, Registers.ClockMonitorIA55,
803                 Registers.ResetControlIA55, Registers.ResetMonitorIA55, NrOfIA55Clocks);
804 
805             DefineRegistersForPeripheral(registerMap, Registers.ClockControlMHU, Registers.ClockMonitorMHU,
806                 Registers.ResetControlMHU, Registers.ResetMonitorMHU, NrOfMhuClocks);
807 
808             DefineRegistersForPeripheral(registerMap, Registers.ClockControlDMAC, Registers.ClockMonitorDMAC,
809                 Registers.ResetControlDMAC, Registers.ResetMonitorDMAC, NrOfDmacClocks);
810 
811             DefineRegistersForPeripheral(registerMap, Registers.ClockControlGTM, Registers.ClockMonitorGTM,
812                 Registers.ResetControlGTM, Registers.ResetMonitorGTM, NrOfGtmClocks);
813 
814             DefineRegistersForPeripheral(registerMap, Registers.ClockControlGPT, Registers.ClockMonitorGPT,
815                 Registers.ResetControlGPT, Registers.ResetMonitorGPT, NrOfGptClocks);
816 
817             DefineRegistersForPeripheral(registerMap, Registers.ClockControlSCIF, Registers.ClockMonitorSCIF,
818                 Registers.ResetControlSCIF, Registers.ResetMonitorSCIF, NrOfScifClocks);
819 
820             DefineRegistersForPeripheral(registerMap, Registers.ClockControlRSPI, Registers.ClockMonitorRSPI,
821                 Registers.ResetControlRSPI, Registers.ResetMonitorRSPI, NrOfRspiClocks);
822 
823             DefineRegistersForPeripheral(registerMap, Registers.ClockControlGPIO, Registers.ClockMonitorGPIO,
824                 Registers.ResetControlGPIO, Registers.ResetMonitorGPIO, NrOfGpioClocks);
825 
826             DefineRegistersForPeripheral(registerMap, Registers.ClockControlI2C, Registers.ClockMonitorI2C,
827                 Registers.ResetControlI2C, Registers.ResetMonitorI2C, NrOfI2cClocks);
828         }
829 
DefineRegistersForPeripheral(Dictionary<long, DoubleWordRegister> registerMap, Registers clockControl, Registers clockMonitor, Registers resetControl, Registers resetMonitor, int nrOfClocks)830         private void DefineRegistersForPeripheral(Dictionary<long, DoubleWordRegister> registerMap, Registers clockControl, Registers clockMonitor,
831             Registers resetControl, Registers resetMonitor, int nrOfClocks)
832         {
833             registerMap.Add((long)clockControl, new DoubleWordRegister(this)
834                 .WithFlags(0, nrOfClocks, out var clockEnabled, name: "CLK_ON")
835                 .WithReservedBits(nrOfClocks, 16 - nrOfClocks)
836                 .WithFlags(16, nrOfClocks, FieldMode.Set | FieldMode.Read,
837                     valueProviderCallback: (_, __) => false,
838                     name: "CLK_ONWEN")
839                 .WithReservedBits(16 + nrOfClocks, 16 - nrOfClocks)
840                 // We have to use register write callback,
841                 // because multiple fields, depending on each other,
842                 // can be changed in one write.
843                 .WithWriteCallback(CreateClockControlWriteCallback(clockControl, clockEnabled))
844             );
845 
846             registerMap.Add((long)clockMonitor, new DoubleWordRegister(this)
847                 .WithFlags(0, nrOfClocks, FieldMode.Read,
848                     valueProviderCallback: CreateClockMonitorValueProviderCallback(clockEnabled),
849                     name: "CLK_MON")
850                 .WithReservedBits(nrOfClocks, 32 - nrOfClocks)
851             );
852 
853             // We don't really implement resets, but we still should log
854             // if we write to register when write is disabled.
855             registerMap.Add((long)resetControl, new DoubleWordRegister(this)
856                 .WithFlags(0, nrOfClocks, out var resetApplied,
857                     valueProviderCallback: (_, __) => false,
858                     name: "UNIT_RSTB")
859                 .WithReservedBits(nrOfClocks, 16 - nrOfClocks)
860                 .WithFlags(16, nrOfClocks, FieldMode.Set | FieldMode.Read,
861                     valueProviderCallback: (_, __) => false,
862                     name: "UNIT_RSTWEN")
863                 .WithReservedBits(16 + nrOfClocks, 16 - nrOfClocks)
864                 // We have to use register write callback,
865                 // because multiple fields, depending on each other,
866                 // can be changed in one write.
867                 .WithWriteCallback(CreateResetControlWriteCallback(resetControl, resetApplied))
868             );
869 
870             // Reset is instantenous, so we always return 0, which means that we aren't in reset state.
871             registerMap.Add((long)resetMonitor, new DoubleWordRegister(this)
872                 .WithFlags(0, nrOfClocks, FieldMode.Read,
873                     valueProviderCallback: CreateResetMonitorValueProviderCallback(resetApplied),
874                     name: "RST_MON")
875                 .WithReservedBits(nrOfClocks, 32 - nrOfClocks)
876             );
877         }
878 
CreateClockControlWriteCallback(Registers register, IFlagRegisterField[] clockEnable)879         private Action<uint, uint> CreateClockControlWriteCallback(Registers register, IFlagRegisterField[] clockEnable)
880         {
881             return (oldVal, newVal) =>
882             {
883                 var invalidClocks = GetInvalidBits(oldVal, newVal, ClockEnableBitsOffset,
884                     ClockEnableBitsSize, ClockWriteEnableBitsOffset, ClockWriteEnableBitsSize);
885 
886                 if(invalidClocks != 0)
887                 {
888                     BitHelper.ForeachActiveBit(invalidClocks, clockIdx =>
889                     {
890                         this.WarningLog(
891                             "Trying to toggle clock {0} in register {1}. Writing to this clock is disabled. Clock status won't be changed.",
892                             clockIdx,
893                             register
894                         );
895                         clockEnable[clockIdx].Value = !clockEnable[clockIdx].Value;
896                     });
897                 }
898             };
899          }
900 
CreateResetControlWriteCallback(Registers register, IFlagRegisterField[] resetApplied)901         private Action<uint, uint> CreateResetControlWriteCallback(Registers register, IFlagRegisterField[] resetApplied)
902         {
903             return (oldVal, newVal) =>
904             {
905                 var invalidResets = GetInvalidBits(oldVal, newVal, ResetEnableBitsOffset,
906                     ResetEnableBitsSize, ResetWriteEnableBitsOffset, ResetWriteEnableBitsSize);
907 
908                 if(invalidResets != 0)
909                 {
910                     BitHelper.ForeachActiveBit(invalidResets, resetIdx =>
911                     {
912                         this.WarningLog(
913                             "Trying to toggle reset signal {0} in register {1}. Writing to this signal is disabled. Signal status won't be changed.",
914                             resetIdx,
915                             register
916                         );
917                         resetApplied[resetIdx].Value = !resetApplied[resetIdx].Value;
918                     });
919                 }
920             };
921         }
922 
CreateWatchdogTimerControlRegister(int id)923         private DoubleWordRegister CreateWatchdogTimerControlRegister(int id)
924         {
925             return new DoubleWordRegister(this, 0x00010000)
926                 .WithFlag(0, name: "WDTSTOP",
927                     valueProviderCallback: _ => watchdogs[id]?.ForceStop ?? false,
928                     writeCallback: (_, val) =>
929                     {
930                         if(watchdogs[id] != null)
931                         {
932                             watchdogs[id].ForceStop = val;
933                         }
934                     }
935                 )
936                 .WithReservedBits(1, 15)
937                 .WithTaggedFlag("WDTSTOPMASK", 16)
938                 .WithReservedBits(17, 15);
939         }
940 
CreateClockMonitorValueProviderCallback(IFlagRegisterField[] clockEnabled)941         private Func<int, bool, bool> CreateClockMonitorValueProviderCallback(IFlagRegisterField[] clockEnabled)
942         {
943             return (clockIdx, _) => clockEnabled[clockIdx].Value;
944         }
945 
CreateResetMonitorValueProviderCallback(IFlagRegisterField[] resetApplied)946         private Func<int, bool, bool> CreateResetMonitorValueProviderCallback(IFlagRegisterField[] resetApplied)
947         {
948             return (resetIdx, _) =>
949             {
950                 var retVal = !resetApplied[resetIdx].Value;
951                 resetApplied[resetIdx].Value = true;
952                 return retVal;
953             };
954         }
955 
GetInvalidBits(uint oldVal, uint newVal, int valueOffset, int valueSize, int maskOffset, int maskSize)956         private uint GetInvalidBits(uint oldVal, uint newVal, int valueOffset, int valueSize, int maskOffset, int maskSize)
957         {
958             var mask = BitHelper.GetValue(newVal, maskOffset, maskSize);
959             oldVal = BitHelper.GetValue(oldVal, valueOffset, valueSize);
960             newVal = BitHelper.GetValue(newVal, valueOffset, valueSize);
961 
962             // We mark as invalid, bits that changed, but were not masked.
963             var changed = oldVal ^ newVal;
964             var invalid = changed & ~mask;
965 
966             return invalid;
967         }
968 
969         private ulong CortexA55Core1ResetVector => (cortexA55Core1ResetVectorLow.Value << 2) | (cortexA55Core1ResetVectorHigh.Value << 32);
970         private bool HasTwoCortexA55Cores => cpu1 != null;
971 
972         private IFlagRegisterField cortexA55Core1PowerTransitionReq;
973         private IEnumRegisterField<PowerTransitionState> cortexA55Core1PowerTransitionState;
974         private IValueRegisterField cortexA55Core1ResetVectorLow;
975         private IValueRegisterField cortexA55Core1ResetVectorHigh;
976 
977         private RenesasRZG_Watchdog[] watchdogs = new RenesasRZG_Watchdog[MaxWatchdogCount];
978 
979         private readonly ICPU cpu0;
980         private readonly ICPU cpu1;
981 
982         private const int NrOfCa55Clocks = 13;
983         private const int NrOfGicClocks = 2;
984         private const int NrOfIA55Clocks = 2;
985         private const int NrOfMhuClocks = 1;
986         private const int NrOfDmacClocks = 2;
987         private const int NrOfGtmClocks = 3;
988         private const int NrOfGptClocks = 1;
989         private const int NrOfI2cClocks = 4;
990         private const int NrOfScifClocks = 5;
991         private const int NrOfRspiClocks = 3;
992         private const int NrOfGpioClocks = 1;
993 
994         private const int ClockEnableBitsOffset = 0;
995         private const int ClockEnableBitsSize = 16;
996         private const int ClockWriteEnableBitsOffset = 16;
997         private const int ClockWriteEnableBitsSize = 16;
998         private const int ResetEnableBitsOffset = 0;
999         private const int ResetEnableBitsSize = 16;
1000         private const int ResetWriteEnableBitsOffset = 16;
1001         private const int ResetWriteEnableBitsSize = 16;
1002         private const int MaxWatchdogCount = 3;
1003 
1004         private const long CPGOffset = 0;
1005         private const long SYSCOffset = 0x10_000;
1006 
1007         private enum PowerTransitionState
1008         {
1009             Off = 0x0,
1010             OffEmulated = 0x1,
1011             On = 0x8,
1012         }
1013 
1014         private enum Registers : long
1015         {
1016             WDTOverflowSystemReset                     = 0xB10 + CPGOffset, // CPG_WDTOVF_RST
1017             WDTResetSelector                           = 0xB14 + CPGOffset, // CPG_WDTRST_SEL
1018             CortexA55Core1PowerStatusMonitor           = 0xB40 + CPGOffset, // CPG_CORE1_PCHMON
1019             CortexA55Core1PowerStatusControl           = 0xB44 + CPGOffset, // CPG_CORE1_PCHCTL
1020 
1021             // Clock Control
1022             ClockControlCA55                           = 0x500 + CPGOffset, // CPG_CLKON_CA55
1023             ClockControlGIC                            = 0x514 + CPGOffset, // CPG_CLKON_GIC600
1024             ClockControlIA55                           = 0x518 + CPGOffset, // CPG_CLKON_IA55
1025             ClockControlMHU                            = 0x520 + CPGOffset, // CPG_CLKON_MHU
1026             ClockControlDMAC                           = 0x52C + CPGOffset, // CPG_CLKON_DAMC_REG
1027             ClockControlGTM                            = 0x534 + CPGOffset, // CPG_CLKON_GTM
1028             ClockControlGPT                            = 0x540 + CPGOffset, // CPG_CLKON_GPT
1029             ClockControlI2C                            = 0x580 + CPGOffset, // CPG_CLKON_I2C
1030             ClockControlSCIF                           = 0x584 + CPGOffset, // CPG_CLKON_SCIF
1031             ClockControlRSPI                           = 0x590 + CPGOffset, // CPG_CLKON_RSPI
1032             ClockControlGPIO                           = 0x598 + CPGOffset, // CPG_CLKON_GPIO
1033 
1034             // Clock Monitor
1035             ClockMonitorCA55                           = 0x680 + CPGOffset, // CPG_CLMON_CA55
1036             ClockMonitorGIC                            = 0x694 + CPGOffset, // CPG_CLKMON_GIC600
1037             ClockMonitorIA55                           = 0x698 + CPGOffset, // CPG_CLKMON_IA55
1038             ClockMonitorMHU                            = 0x6A0 + CPGOffset, // CPG_CLMON_MHU
1039             ClockMonitorDMAC                           = 0x6AC + CPGOffset, // CPG_CLKMON_DAMC_REG
1040             ClockMonitorGTM                            = 0x6B4 + CPGOffset, // CPG_CLMON_GTM
1041             ClockMonitorGPT                            = 0x6C0 + CPGOffset, // CPG_CLMON_GPT
1042             ClockMonitorI2C                            = 0x700 + CPGOffset, // CPG_CLMON_I2C
1043             ClockMonitorSCIF                           = 0x704 + CPGOffset, // CPG_CLMON_SCIF
1044             ClockMonitorRSPI                           = 0x710 + CPGOffset, // CPG_CLMON_RSPI
1045             ClockMonitorGPIO                           = 0x718 + CPGOffset, // CPG_CLMON_GPIO
1046 
1047             // Reset Control
1048             ResetControlCA55                           = 0x800 + CPGOffset, // CPG_RST_CA55
1049             ResetControlGIC                            = 0x814 + CPGOffset, // CPG_RST_GIC600
1050             ResetControlIA55                           = 0x818 + CPGOffset, // CPG_RST_IA55
1051             ResetControlMHU                            = 0x820 + CPGOffset, // CPG_RST_MHU
1052             ResetControlDMAC                           = 0x82C + CPGOffset, // CPG_RST_DMAC
1053             ResetControlGTM                            = 0x834 + CPGOffset, // CPG_RST_GTM
1054             ResetControlGPT                            = 0x844 + CPGOffset, // CPG_RST_GPT
1055             ResetControlI2C                            = 0x880 + CPGOffset, // CPG_RST_I2C
1056             ResetControlSCIF                           = 0x884 + CPGOffset, // CPG_RST_SCIF
1057             ResetControlRSPI                           = 0x890 + CPGOffset, // CPG_RST_RSPI
1058             ResetControlGPIO                           = 0x898 + CPGOffset, // CPG_RST_GPIO
1059 
1060             // Reset Monitor
1061             ResetMonitorCA55                           = 0x980 + CPGOffset, // CPG_RSTMON_CA55
1062             ResetMonitorGIC                            = 0x994 + CPGOffset, // CPG_RSTMON_GIC600
1063             ResetMonitorIA55                           = 0x998 + CPGOffset, // CPG_RSTMON_IA55
1064             ResetMonitorMHU                            = 0x9A0 + CPGOffset, // CPG_RSTMON_MHU
1065             ResetMonitorDMAC                           = 0x9AC + CPGOffset, // CPG_RSTMON_DMAC
1066             ResetMonitorGTM                            = 0x9B4 + CPGOffset, // CPG_RSTMON_GTM
1067             ResetMonitorGPT                            = 0x9C0 + CPGOffset, // CPG_RSTMON_GPT
1068             ResetMonitorI2C                            = 0xA00 + CPGOffset, // CPG_RSTMON_I2C
1069             ResetMonitorSCIF                           = 0xA04 + CPGOffset, // CPG_RSTMON_SCIF
1070             ResetMonitorRSPI                           = 0xA10 + CPGOffset, // CPG_RSTMON_RSPI
1071             ResetMonitorGPIO                           = 0xA18 + CPGOffset, // CPG_RSTMON_GPIO
1072 
1073             MasterAccessControl0                       = 0x000 + SYSCOffset,
1074             MasterAccessControl1                       = 0x004 + SYSCOffset,
1075             MasterAccessControl2                       = 0x008 + SYSCOffset,
1076             MasterAccessControl3                       = 0x00C + SYSCOffset,
1077             MasterAccessControl4                       = 0x010 + SYSCOffset,
1078             SlaveAccessControl0                        = 0x100 + SYSCOffset,
1079             SlaveAccessControl1                        = 0x104 + SYSCOffset,
1080             SlaveAccessControl2                        = 0x108 + SYSCOffset,
1081             SlaveAccessControl3                        = 0x10C + SYSCOffset,
1082             SlaveAccessControl4                        = 0x110 + SYSCOffset,
1083             SlaveAccessControl5                        = 0x114 + SYSCOffset,
1084             SlaveAccessControl6                        = 0x118 + SYSCOffset,
1085             SlaveAccessControl7                        = 0x11C + SYSCOffset,
1086             SlaveAccessControl8                        = 0x120 + SYSCOffset,
1087             SlaveAccessControl10                       = 0x128 + SYSCOffset,
1088             SlaveAccessControl12                       = 0x130 + SYSCOffset,
1089             SlaveAccessControl13                       = 0x134 + SYSCOffset,
1090             SlaveAccessControl14                       = 0x138 + SYSCOffset,
1091             ErrorCorrectingCodeRam0Settings            = 0x200 + SYSCOffset,
1092             ErrorCorrectingCodeRam0AccessControl       = 0x204 + SYSCOffset,
1093             ErrorCorrectingCodeRam1Settings            = 0x210 + SYSCOffset,
1094             ErrorCorrectingCodeRam1AccessControl       = 0x214 + SYSCOffset,
1095             WatchdogTimer0Control                      = 0x220 + SYSCOffset,
1096             WatchdogTimer1Control                      = 0x230 + SYSCOffset,
1097             WatchdogTimer2Control                      = 0x240 + SYSCOffset,
1098             GigabitEthernet0Config                     = 0x330 + SYSCOffset,
1099             GigabitEthernet1Config                     = 0x340 + SYSCOffset,
1100             I2c0Config                                 = 0x400 + SYSCOffset,
1101             I2c1Config                                 = 0x410 + SYSCOffset,
1102             I2c2Config                                 = 0x420 + SYSCOffset,
1103             I2c3Config                                 = 0x430 + SYSCOffset,
1104             CortexM33Config0                           = 0x804 + SYSCOffset,
1105             CortexM33Config1                           = 0x808 + SYSCOffset,
1106             CortexM33Config2                           = 0x80C + SYSCOffset,
1107             CortexM33Config3                           = 0x810 + SYSCOffset,
1108             CortexM33Lock                              = 0x814 + SYSCOffset,
1109             CortexA55Core0ResetVectorAddressLowConfig  = 0x858 + SYSCOffset,
1110             CortexA55Core0ResetVectorAddressHighConfig = 0x85C + SYSCOffset,
1111             CortexA55Core1ResetVectorAddressLowConfig  = 0x860 + SYSCOffset,
1112             CortexA55Core1ResetVectorAddressHighConfig = 0x864 + SYSCOffset,
1113             LsiModeSignal                              = 0xA00 + SYSCOffset,
1114             LsiDeviceId                                = 0xA04 + SYSCOffset,
1115             LsiProduct                                 = 0xA08 + SYSCOffset,
1116             AddressOffset0                             = 0xC00 + SYSCOffset,
1117             AddressOffset1                             = 0xC04 + SYSCOffset,
1118             AddressOffset2                             = 0xC08 + SYSCOffset,
1119             AddressOffset3                             = 0xC0C + SYSCOffset,
1120             AddressOffset4                             = 0xC10 + SYSCOffset,
1121             AddressOffset5                             = 0xC14 + SYSCOffset,
1122             AddressOffset6                             = 0xC18 + SYSCOffset,
1123             LowPowerSequenceControl1                   = 0xD04 + SYSCOffset,
1124             LowPowerSequenceControl2                   = 0xD08 + SYSCOffset,
1125             LowPowerSequenceControl5                   = 0xD14 + SYSCOffset,
1126             LowPowerSequenceControl6                   = 0xD18 + SYSCOffset,
1127             LowPowerSequenceControl7                   = 0xD1C + SYSCOffset,
1128             LowPowerSequenceCortexM33Control0          = 0xD24 + SYSCOffset,
1129             CortexA55ClockControl1                     = 0xD38 + SYSCOffset,
1130             CortexA55ClockControl2                     = 0xD3C + SYSCOffset,
1131             CortexA55ClockControl3                     = 0xD40 + SYSCOffset,
1132             GpuLowPowerSequenceControl                 = 0xD50 + SYSCOffset,
1133             General0                                   = 0xE00 + SYSCOffset,
1134             General1                                   = 0xE04 + SYSCOffset,
1135             General2                                   = 0xE08 + SYSCOffset,
1136             General3                                   = 0xE0C + SYSCOffset,
1137         }
1138     }
1139 }
1140