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