1 // 2 // Copyright (c) 2010-2018 Antmicro 3 // Copyright (c) 2011-2015 Realtime Embedded 4 // 5 // This file is licensed under the MIT License. 6 // Full license text is available in 'licenses/MIT.txt'. 7 // 8 9 using Antmicro.Renode.Core; 10 using Antmicro.Renode.Logging; 11 using Antmicro.Renode.Peripherals.Bus; 12 using System.Threading; 13 using Antmicro.Renode.UserInterface; 14 15 namespace Antmicro.Renode.Peripherals.Miscellaneous 16 { 17 [Icon("wrench")] 18 public class ArmSysCtl : IDoubleWordPeripheral 19 { ArmSysCtl(IMachine machine)20 public ArmSysCtl(IMachine machine) 21 { 22 this.machine = machine; 23 Reset(); 24 } 25 ArmSysCtl(IMachine machine,uint procId)26 public ArmSysCtl(IMachine machine,uint procId) 27 { 28 this.machine = machine; 29 this.ProcId=procId; 30 Reset(); 31 } 32 ReadDoubleWord(long offset)33 public uint ReadDoubleWord (long offset) 34 { 35 switch((CTL)offset) 36 { 37 case CTL.Id: 38 return SysId; 39 case CTL.Sw: 40 return 0; 41 case CTL.Led: 42 return Leds; 43 case CTL.Lock: 44 return LockVal; 45 case CTL.OSC0: 46 return 0; 47 case CTL.OSC1: 48 return 0; 49 case CTL.OSC2: 50 return 0; 51 case CTL.OSC3: 52 return 0; 53 case CTL.OSC4: 54 return 0; 55 case CTL.MHz100: 56 return 0; 57 case CTL.CfgData1: 58 return CfgData1; 59 case CTL.CfgData2: 60 return CfgData2; 61 case CTL.Flags: 62 return Flags; 63 case CTL.NvFlags: 64 return NvFlags; 65 case CTL.ResetCtl: 66 return ResetLevel; 67 case CTL.PCICtl: 68 return 1; 69 case CTL.Mci: 70 return 0; 71 case CTL.Flash: 72 return 0; 73 case CTL.Clcd: 74 return 0x1000; 75 case CTL.ClcdSer: 76 return 0; 77 case CTL.BootCs: 78 return 0; 79 case CTL.Mhz24: 80 //TODO: verify 81 uint v = unchecked((uint)((machine.ElapsedVirtualTime.TimeElapsed).TotalSeconds*24000000)); 82 return v; 83 case CTL.Misc: 84 return 0; 85 case CTL.ProcId0: 86 return ProcId; 87 case CTL.ProcId1: 88 return 0xff000000; 89 case CTL.Dmapsr0: 90 return 0; 91 case CTL.Dmapsr1: 92 return 0; 93 case CTL.Dmapsr2: 94 return 0; 95 case CTL.IOSel: 96 return 0; 97 case CTL.PldCtl: 98 return 0; 99 case CTL.BusId: 100 return 0; 101 case CTL.OSCRESET0: 102 return 0; 103 case CTL.OSCRESET1: 104 return 0; 105 case CTL.OSCRESET2: 106 return 0; 107 case CTL.OSCRESET3: 108 return 0; 109 case CTL.OSCRESET4: 110 return 0; 111 case CTL.CFGDATA: 112 return CfgData; 113 case CTL.CFGCTRL: 114 return CfgCtrl; 115 case CTL.CFGSTAT: 116 return CfgStat; 117 case CTL.SYS_TEST_OSC0: 118 return 0; 119 case CTL.SYS_TEST_OSC1: 120 return 0; 121 case CTL.SYS_TEST_OSC2: 122 return 0; 123 case CTL.SYS_TEST_OSC3: 124 return 0; 125 case CTL.SYS_TEST_OSC4: 126 return 0; 127 default: 128 this.LogUnhandledRead(offset); 129 return 0; 130 } 131 } 132 133 private const int LOCK_VALUE = 0xa05f; 134 WriteDoubleWord(long offset, uint value)135 public void WriteDoubleWord (long offset, uint value) 136 { 137 switch((CTL)offset) 138 { 139 case CTL.Led: 140 Leds = value; 141 break; 142 case CTL.OSC0: 143 break; 144 case CTL.OSC1: 145 break; 146 case CTL.OSC2: 147 break; 148 case CTL.OSC3: 149 break; 150 case CTL.OSC4: 151 break; 152 case CTL.Lock: 153 if(value == LOCK_VALUE) 154 { 155 LockVal = (ushort) value; 156 } 157 else 158 { 159 LockVal = (ushort)(value & 0x7fff); 160 } 161 break; 162 case CTL.CfgData1: 163 CfgData1 = value; 164 break; 165 case CTL.CfgData2: 166 CfgData2 = value; 167 break; 168 case CTL.Flags: 169 Flags |= value; 170 break; 171 case CTL.FlagsClr: 172 Flags &= ~value; 173 break; 174 case CTL.NvFlags: 175 NvFlags |= value; 176 break; 177 case CTL.NvFlagsClr: 178 NvFlags &= ~value; 179 break; 180 case CTL.ResetCtl: 181 if(LockVal == LOCK_VALUE) 182 { 183 ResetLevel = value; 184 if (ResetLevel == 0x105) 185 { 186 this.Log(LogLevel.Info, "System reset triggered."); 187 new Thread(() => machine.Reset()) { IsBackground = true }.Start(); 188 } 189 } 190 break; 191 case CTL.PCICtl: 192 break; 193 case CTL.Flash: 194 break; 195 case CTL.Clcd: 196 break; 197 case CTL.ClcdSer: 198 break; 199 case CTL.Dmapsr0: 200 break; 201 case CTL.Dmapsr1: 202 break; 203 case CTL.Dmapsr2: 204 break; 205 case CTL.IOSel: 206 break; 207 case CTL.PldCtl: 208 break; 209 case CTL.BusId: 210 break; 211 case CTL.ProcId0: 212 break; 213 case CTL.ProcId1: 214 break; 215 case CTL.CFGDATA: 216 CfgData =value; 217 break; 218 case CTL.CFGCTRL: 219 if(value == MachineReset) 220 { 221 this.Log(LogLevel.Info, "System reset triggered."); 222 new Thread(() => machine.Reset()) { IsBackground = true }.Start(); 223 } 224 if(value == MachineShutdown) 225 { 226 this.Log(LogLevel.Info, "System shutdown triggered."); 227 /* Put shutdown code here */ 228 } 229 CfgCtrl = (uint)(value & (uint)(~(3u << 18))); 230 CfgStat=1; 231 break; 232 case CTL.CFGSTAT: 233 CfgStat=value& 3; 234 break; 235 case CTL.OSCRESET0: 236 break; 237 case CTL.OSCRESET1: 238 break; 239 case CTL.OSCRESET2: 240 break; 241 case CTL.OSCRESET3: 242 break; 243 case CTL.OSCRESET4: 244 break; 245 default: 246 this.LogUnhandledWrite(offset, value); 247 return; 248 } 249 } 250 Reset()251 public void Reset () 252 { 253 Leds = 0; 254 LockVal = 0; 255 CfgData1 = 0; 256 CfgData2 = 0; 257 Flags = 0; 258 ResetLevel = 0; 259 } 260 261 private uint SysId = 0x41007004; 262 private uint Leds; 263 private ushort LockVal; 264 private uint CfgData1; 265 private uint CfgData2; 266 private uint Flags; 267 private uint NvFlags; 268 private uint ResetLevel; 269 private uint CfgData; 270 private uint CfgCtrl; 271 private uint CfgStat; 272 private uint ProcId = 0x02000000; 273 private uint MachineReset = 0xC0900000; 274 private uint MachineShutdown = 0xC0800000; 275 private readonly IMachine machine; 276 277 private enum CTL : uint 278 { 279 Id = 0x00, 280 Sw = 0x04, 281 Led = 0x08, 282 OSC0 = 0x0c, 283 OSC1 = 0x10, 284 OSC2 = 0x14, 285 OSC3 = 0x18, 286 OSC4 = 0x1c, 287 Lock = 0x20, 288 MHz100 = 0x24, 289 CfgData1 = 0x28, 290 CfgData2 = 0x2c, 291 Flags = 0x30, 292 FlagsClr = 0x34, 293 NvFlags = 0x38, 294 NvFlagsClr = 0x3c, 295 ResetCtl = 0x40, 296 PCICtl = 0x44, 297 Mci = 0x48, 298 Flash = 0x4c, 299 Clcd = 0x50, 300 ClcdSer = 0x54, 301 BootCs = 0x58, 302 Mhz24 = 0x5c, 303 Misc = 0x60, 304 Dmapsr0 = 0x64, 305 Dmapsr1 = 0x68, 306 Dmapsr2 = 0x6c, 307 IOSel = 0x70, 308 PldCtl = 0x74, 309 BusId = 0x80, 310 ProcId0 = 0x84, 311 ProcId1 = 0x88, 312 OSCRESET0 = 0x8c, 313 OSCRESET1 = 0x90, 314 OSCRESET2 = 0x94, 315 OSCRESET3 = 0x98, 316 OSCRESET4 = 0x9c, 317 CFGDATA = 0xa0, 318 CFGCTRL = 0xa4, 319 CFGSTAT = 0xa8, 320 SYS_TEST_OSC0 = 0xc0, 321 SYS_TEST_OSC1 = 0xc4, 322 SYS_TEST_OSC2 = 0xc8, 323 SYS_TEST_OSC3 = 0xcc, 324 SYS_TEST_OSC4 = 0xd0 325 } 326 } 327 } 328 329