1 //
2 // Copyright (c) 2010-2025 Antmicro
3 // Copyright (c) 2022-2025 Silicon Labs
4 //
5 // This file is licensed under the MIT License.
6 // Full license text is available in 'licenses/MIT.txt'.
7 //
8 
9 using System;
10 using System.IO;
11 using System.Collections.Generic;
12 using Antmicro.Renode.Core;
13 using Antmicro.Renode.Core.Structure.Registers;
14 using Antmicro.Renode.Logging;
15 using Antmicro.Renode.Exceptions;
16 using Antmicro.Renode.Peripherals.CPU;
17 using Antmicro.Renode.Peripherals.Bus;
18 
19 namespace Antmicro.Renode.Peripherals.Miscellaneous.SiLabs
20 {
21     public partial class EFR32xG2_LFXO_1
22     {
EFR32xG2_LFXO_1_Constructor()23         partial void EFR32xG2_LFXO_1_Constructor()
24         {
25         }
26 
BusFault(uint exception)27         private void BusFault(uint exception)
28         {
29             this.Log(LogLevel.Error, "LFXO is locked, BusFault!!");
30             if (
31                 machine.SystemBus.TryGetCurrentCPU(out var cpu)
32                 && cpu is TranslationCPU translationCPU
33             )
34             {
35                 translationCPU.RaiseException(exception);
36             }
37         }
38 
Ctrl_Write(uint a, uint b)39         partial void Ctrl_Write(uint a, uint b)
40         {
41             if (status_lock_bit.Value == STATUS_LOCK.LOCKED)
42             {
43                 BusFault(EXCP_PREFETCH_ABORT);
44             }
45         }
46 
Cfg_Write(uint a, uint b)47         partial void Cfg_Write(uint a, uint b)
48         {
49             if (status_lock_bit.Value == STATUS_LOCK.LOCKED)
50             {
51                 BusFault(EXCP_PREFETCH_ABORT);
52             }
53         }
54 
Cfg1_Write(uint a, uint b)55         partial void Cfg1_Write(uint a, uint b)
56         {
57             if (status_lock_bit.Value == STATUS_LOCK.LOCKED)
58             {
59                 BusFault(EXCP_PREFETCH_ABORT);
60             }
61         }
62 
Cal_Write(uint a, uint b)63         partial void Cal_Write(uint a, uint b)
64         {
65             if (status_lock_bit.Value == STATUS_LOCK.LOCKED)
66             {
67                 BusFault(EXCP_PREFETCH_ABORT);
68             }
69         }
70 
Ctrl_Forceen_Write(bool a, bool b)71         partial void Ctrl_Forceen_Write(bool a, bool b)
72         {
73             oscillatorForce = (b == true);
74         }
75 
Ctrl_Disondemand_Write(bool a, bool b)76         partial void Ctrl_Disondemand_Write(bool a, bool b)
77         {
78             oscillatorOnDemand = (b != true);
79         }
80 
Lock_Lockkey_Write(ulong a, ulong b)81         partial void Lock_Lockkey_Write(ulong a, ulong b)
82         {
83             if (b == 0x1A20)
84             {
85                 status_lock_bit.Value = STATUS_LOCK.UNLOCKED;
86             }
87             else
88             {
89                 status_lock_bit.Value = STATUS_LOCK.LOCKED;
90             }
91         }
92 
Status_Rdy_ValueProvider(bool a)93         partial void Status_Rdy_ValueProvider(bool a)
94         {
95             status_rdy_bit.Value = oscillatorUsed;
96         }
97 
Status_Ens_ValueProvider(bool a)98         partial void Status_Ens_ValueProvider(bool a)
99         {
100             status_ens_bit.Value = oscillatorUsed;
101         }
102 
If_Rdy_ValueProvider(bool a)103         partial void If_Rdy_ValueProvider(bool a)
104         {
105             if_rdy_bit.Value = oscillatorUsed && ien_rdy_bit.Value;
106         }
107 
108         private bool oscillatorEnabled
109         {
110             get { return cmu.OscLfxoEnabled; }
111         }
112 
113         private bool oscillatorUsed
114         {
115             get { return oscillatorForce || oscillatorOnDemand; }
116         }
117 
118         private bool oscillatorOnDemand = false;
119         private bool oscillatorForce = false;
120         // See constant definitions in src/Infrastructure/src/Emulator/Cores/tlib/arch/arm/cpu.h
121         private const uint EXCP_PREFETCH_ABORT = 3;
122     }
123 }
124