1 //
2 // Copyright (c) 2010-2023 Antmicro
3 //
4 // This file is licensed under the MIT License.
5 // Full license text is available in 'licenses/MIT.txt'.
6 //
7 using System.Collections.Generic;
8 using Antmicro.Renode.Core;
9 using Antmicro.Renode.Core.Structure.Registers;
10 using Antmicro.Renode.Exceptions;
11 using Antmicro.Renode.Logging;
12 using Antmicro.Renode.Peripherals.Bus;
13 using Antmicro.Renode.Utilities;
14 
15 namespace Antmicro.Renode.Peripherals.Miscellaneous
16 {
17     class MAX32650_TPU : BasicDoubleWordPeripheral, IKnownSize
18     {
MAX32650_TPU(IMachine machine)19         public MAX32650_TPU(IMachine machine) : base(machine)
20         {
21             IRQ = new GPIO();
22 
23             DefineRegisters();
24         }
25 
26         public long Size => 0x1000;
27 
28         public GPIO IRQ { get; }
29 
CalculateCrc32()30         private void CalculateCrc32()
31         {
32             try
33             {
34                 byte[] data;
35                 data = sysbus.ReadBytes((ulong)dmaSourceAddress.Value, (int)dmaDataLength.Value, onlyMemory: true);
36                 crcEngine.Update(data);
37                 crcValue.Value = crcEngine.Value;
38                 dmaFinished.Value = true;
39                 crcFinished.Value = true;
40             }
41             catch(RecoverableException exception)
42             {
43                 this.Log(LogLevel.Warning, "Error occured when reading memory to calculate CRC: {0}", exception.Message);
44                 errorOccured.Value = true;
45             }
46 
47             operationFinished.Value |= crcFinished.Value;
48             UpdateInterrupts();
49         }
50 
UpdateCRCEngine()51         private void UpdateCRCEngine()
52         {
53             var polynomial = BitHelper.ReverseBits((uint)crcPolynomial.Value);
54             crcEngine = new CRCEngine(polynomial, 32, init: (uint)crcValue.Value);
55         }
56 
UpdateInterrupts()57         private void UpdateInterrupts()
58         {
59             if(interruptEnabled.Value)
60             {
61                 IRQ.Set(operationFinished.Value | errorOccured.Value);
62             }
63             else
64             {
65                 IRQ.Unset();
66             }
67         }
68 
ResetKnownRegisters()69         private void ResetKnownRegisters()
70         {
71             dmaSourceAddress.Value = 0x00000000;
72             dmaDataLength.Value = 0x00000000;
73             crcPolynomial.Value = DefaultCRCPolynomial;
74             crcValue.Value = DefaultCRCSeed;
75 
76             UpdateCRCEngine();
77         }
78 
DefineRegisters()79         private void DefineRegisters()
80         {
81             Registers.CryptoControl.Define(this)
82                 .WithFlag(0, FieldMode.WriteOneToClear, name: "CRYPTO_CTRL.rst",
83                     // Writing '1' to this field causes peripheral to clear all its
84                     // internal cryptographic states as well as related registers.
85                     // We are not supposed to clear configuration, thus
86                     // *_CTRL registers are omitted.
87                     writeCallback: (_, value) => { if(value) ResetKnownRegisters(); })
88                 .WithFlag(1, out interruptEnabled, name: "CRYPTO_CTRL.int",
89                     changeCallback: (_, __) => UpdateInterrupts())
90                 .WithTaggedFlag("CRYPTO_CTRL.src", 2)
91                 .WithReservedBits(3, 1)
92                 .WithTaggedFlag("CRYPTO_CTRL.bso", 4)
93                 .WithTaggedFlag("CRYPTO_CTRL.bsi", 5)
94                 .WithTaggedFlag("CRYPTO_CTRL.wait_end", 6)
95                 .WithTaggedFlag("CRYPTO_CTRL.wait_pol", 7)
96                 .WithTag("CRYPTO_CTRL.wrsrc", 8, 2)
97                 .WithEnumField<DoubleWordRegister, ReadFIFOSource>(10, 2, name: "CRYPTO_CTRL.rdsrc",
98                     changeCallback: (_, value) =>
99                     {
100                         if(value != ReadFIFOSource.DMAorAPB)
101                         {
102                             this.Log(LogLevel.Warning, "Tried to change FIFO source to {0}, but only DMA is currently supported; ignored", value);
103                         }
104                     })
105                 .WithReservedBits(12, 2)
106                 .WithTaggedFlag("CRYPTO_CTRL.flag_mode", 14)
107                 .WithTaggedFlag("CRYPTO_CTRL.dmadnemsk", 15)
108                 .WithReservedBits(16, 8)
109                 .WithFlag(24, out dmaFinished, name: "CRYPTO_CTRL.dma_done")
110                 .WithFlag(25, out crcFinished, name: "CRYPTO_CTRL.gls_done",
111                     changeCallback: (_, __) => UpdateInterrupts())
112                 .WithTaggedFlag("CRYPTO_CTRL.hsh_done", 26)
113                 .WithTaggedFlag("CRYPTO_CTRL.cph_done", 27)
114                 .WithTaggedFlag("CRYPTO_CTRL.maa_done", 28)
115                 .WithFlag(29, out errorOccured, FieldMode.Read, name: "CRYPTO_CTRL.err")
116                 .WithFlag(30, FieldMode.Read, name: "CRYPTO_CTRL.rdy",
117                     valueProviderCallback: _ => true)
118                 .WithFlag(31, out operationFinished, name: "CRYPTO_CTRL.done")
119             ;
120 
121             Registers.CRCControl.Define(this)
122                 .WithFlag(0, out crcEnabled, name: "CRC_CTRL.crc")
123                 .WithFlag(1, name: "CRC_CTRL.msb",
124                     changeCallback: (_, value) =>
125                     {
126                         if(value)
127                         {
128                             this.Log(LogLevel.Warning, "CRC mode changed to MSB, but only LSB is supported; ignoring");
129                         }
130                     })
131                 .WithTaggedFlag("CRC_CTRL.prng", 2)
132                 .WithTaggedFlag("CRC_CTRL.ent", 3)
133                 .WithTaggedFlag("CRC_CTRL.ham", 4)
134                 .WithTaggedFlag("CRC_CTRL.hrst", 5)
135                 .WithReservedBits(6, 26)
136             ;
137 
138             Registers.DMASource.Define(this)
139                 .WithValueField(0, 32, out dmaSourceAddress, name: "DMA_SRC.addr")
140             ;
141 
142             Registers.DMACount.Define(this)
143                 .WithValueField(0, 32, out dmaDataLength, name: "DMA_CNT.addr")
144                 .WithWriteCallback((_, __) => CalculateCrc32());
145                 // According to documentation and HAL implementation, the CRC
146                 // value is calculated after DMA transaction is done. As writing
147                 // to this register starts DMA transaction, we can use it
148                 // as trigger to calculate CRC value.
149             ;
150 
151             Registers.CRCPolynomial.Define(this, DefaultCRCPolynomial)
152                 .WithValueField(0, 32, out crcPolynomial, FieldMode.Write, name: "CRC_POLY.data",
153                     changeCallback: (_, __) => UpdateCRCEngine())
154             ;
155 
156             Registers.CRCValue.Define(this, DefaultCRCSeed)
157                 .WithValueField(0, 32, out crcValue, name: "CRC_VAL.val",
158                     changeCallback: (_, __) => UpdateCRCEngine())
159             ;
160         }
161 
162         private IFlagRegisterField crcEnabled;
163         private IFlagRegisterField interruptEnabled;
164         private IFlagRegisterField dmaFinished;
165         private IFlagRegisterField crcFinished;
166         private IFlagRegisterField errorOccured;
167         private IFlagRegisterField operationFinished;
168 
169         private IValueRegisterField dmaSourceAddress;
170         private IValueRegisterField dmaDataLength;
171 
172         private IValueRegisterField crcPolynomial;
173         private IValueRegisterField crcValue;
174 
175         private CRCEngine crcEngine;
176 
177         private const uint DefaultCRCPolynomial = 0xEDB88320;
178         private const uint DefaultCRCSeed = 0xFFFFFFFF;
179 
180         private enum ReadFIFOSource : byte
181         {
182             DMADisabled = 0,
183             DMAorAPB,
184             RNG,
185             Reserved,
186         }
187 
188         private enum Registers
189         {
190             CryptoControl = 0x00,
191             CipherControl = 0x04,
192             HashControl = 0x08,
193             CRCControl = 0x0C,
194             DMASource = 0x10,
195             DMADestination = 0x14,
196             DMACount = 0x18,
197             MAAControl = 0x1C,
198             DataIn0 = 0x20,
199             DataIn1 = 0x24,
200             DataIn2 = 0x28,
201             DataIn3 = 0x2C,
202             DataOut0 = 0x30,
203             DataOut1 = 0x34,
204             DataOut2 = 0x38,
205             DataOut3 = 0x3C,
206             CRCPolynomial = 0x40,
207             CRCValue = 0x44,
208             PRNG = 0x48,
209             HammingECC = 0x4C,
210             CipherInitialVector0 = 0x50,
211             CipherInitialVector1 = 0x54,
212             CipherInitialVector2 = 0x58,
213             CipherInitialVector3 = 0x5C,
214             CipherKey0 = 0x60,
215             CipherKey1 = 0x64,
216             CipherKey2 = 0x68,
217             CipherKey3 = 0x6C,
218             CipherKey4 = 0x70,
219             CipherKey5 = 0x74,
220             CipherKey6 = 0x78,
221             CipherKey7 = 0x7C,
222             HashMessageDigest0 = 0x80,
223             HashMessageDigest1 = 0x84,
224             HashMessageDigest2 = 0x88,
225             HashMessageDigest3 = 0x8C,
226             HashMessageDigest4 = 0x90,
227             HashMessageDigest5 = 0x94,
228             HashMessageDigest6 = 0x98,
229             HashMessageDigest7 = 0x9C,
230             HashMessageDigest8 = 0xA0,
231             HashMessageDigest9 = 0xA4,
232             HashMessageDigest10 = 0xA8,
233             HashMessageDigest11 = 0xAC,
234             HashMessageDigest12 = 0xB0,
235             HashMessageDigest13 = 0xB4,
236             HashMessageDigest14 = 0xB8,
237             HashMessageDigest15 = 0xBC,
238             HashMessageSize0 = 0xC0,
239             HashMessageSize1 = 0xC4,
240             HashMessageSize2 = 0xC8,
241             HashMessageSize3 = 0xCC,
242             MAAWordSize = 0xD0,
243         }
244     }
245 }
246 
247