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 using System;
9 using Antmicro.Renode.Storage;
10 using Antmicro.Renode.Utilities;
11 using Antmicro.Renode.Logging;
12 using System.IO;
13 using Antmicro.Renode.Exceptions;
14 
15 namespace Antmicro.Renode.Peripherals.SD
16 {
17     public class DeprecatedSDCard : IPeripheral
18     {
DeprecatedSDCard(string imageFile, long? cardSize, bool persistent)19         public DeprecatedSDCard(string imageFile, long? cardSize, bool persistent)
20         {
21             if(String.IsNullOrEmpty(imageFile))
22             {
23                 throw new ConstructionException("No card image file provided.");
24             }
25             else
26             {
27                 if(!persistent)
28                 {
29                     var tempFileName = TemporaryFilesManager.Instance.GetTemporaryFile();
30                     FileCopier.Copy(imageFile, tempFileName, true);
31                     imageFile = tempFileName;
32                 }
33                 file = new SerializableStreamView(new FileStream(imageFile, FileMode.OpenOrCreate));
34             }
35 
36             CardSize = cardSize ?? file.Length;
37 
38             var cardIdentificationBytes = new byte[] {0x01, 0x00, 0x00, 0x00, // 1b always one + 7b CRC (ignored) + 12b manufacturing date + 4b reserved
39                 0x00, 0x00, 0x00, 0x00, // 32b product serial number + 8b product revision
40                 0x45, 0x44, 0x43, 0x42, 0x41, // Product name, 5 character string. "ABCDE" (backwards)
41                 0x00, 0x00, 0x00 // 16b application ID + 8b manufacturer ID
42             };
43 
44             cardIdentification = new uint[4];
45             cardIdentification[0] = BitConverter.ToUInt32(cardIdentificationBytes, 0);
46             cardIdentification[1] = BitConverter.ToUInt32(cardIdentificationBytes, 4);
47             cardIdentification[2] = BitConverter.ToUInt32(cardIdentificationBytes, 8);
48             cardIdentification[3] = BitConverter.ToUInt32(cardIdentificationBytes, 12);
49 
50             cardSpecificData = new uint[4];
51             uint deviceSize = (uint)(CardSize / 0x80000 - 1);
52             cardSpecificData[0] = 0x0a4040af;
53             cardSpecificData[1] = 0x3b377f80 | ((deviceSize & 0xffff) << 16);
54             cardSpecificData[2] = 0x5b590000 | ((deviceSize >> 16) & 0x3f);
55             cardSpecificData[3] = 0x400e0032;
56         }
57 
Reset()58         public void Reset()
59         {
60             opAppInitialized = false;
61             opCodeChecked = false;
62             lastAppOpCodeNormal = false;
63         }
64 
Dispose()65         public void Dispose()
66         {
67             file.Dispose();
68         }
69 
GoIdleState()70         public uint GoIdleState()
71         {
72             if(!lastAppOpCodeNormal)
73             {
74                 return 0x40ff8000;
75             }
76             else
77             {
78                 return 0x900;
79             }
80         }
81 
SendOpCond()82         public uint SendOpCond()
83         {
84             return 0x300000;  // supported voltage: 3.1-3.3V
85         }
86 
SendStatus(bool dataTransfer)87         public uint SendStatus(bool dataTransfer)
88         {
89             if(dataTransfer)
90             {
91                 return 0x0; // initial card status - idle
92             }
93             else
94             {
95                 return (1 << 9) | (1 << 8); // ready for data
96             }
97         }
98 
SendSdConfigurationValue()99         public ulong SendSdConfigurationValue()
100         {
101             return 0xf000ul;
102         }
103 
SetRelativeAddress()104         public uint SetRelativeAddress()
105         {
106             return 0x520 | (cardAddress << 16); // first 16b - relative address of the card
107         }
108 
SelectDeselectCard()109         public uint SelectDeselectCard()
110         {
111             return 0x700;
112         }
113 
SendExtendedCardSpecificData()114         public uint SendExtendedCardSpecificData()
115         {
116             return 0x1aa;
117         }
118 
AllSendCardIdentification()119         public uint[] AllSendCardIdentification()
120         {
121             return cardIdentification;
122         }
123 
AppCommand(uint argument)124         public uint AppCommand(uint argument)
125         {
126             uint result = 0x120;
127             if(!opAppInitialized)
128             {
129                 result |= (1 << 22);
130                 opAppInitialized = true;
131             }
132             if(((argument >> 16) & 0xffff) == cardAddress)
133             {
134                 result |= (1 << 11);
135             }
136             return result;
137         }
138 
Switch()139         public uint Switch()
140         {
141             return 0x900;
142         }
143 
SendAppOpCode(uint args)144         public uint SendAppOpCode(uint args)
145         {
146             uint result = 0x40ff8000;
147             lastAppOpCodeNormal = true;
148             if(args == 0x40200000)
149             {
150                 if(opCodeChecked)
151                 {
152                     result |= 0x80000000;
153                     lastAppOpCodeNormal = false;
154                 }
155                 else
156                 {
157                     opCodeChecked = true;
158                 }
159             }
160             return result;
161         }
162 
SendCardSpecificData()163         public uint[] SendCardSpecificData()
164         {
165             return cardSpecificData;
166         }
167 
ReadData(long offset, int size)168         public byte[] ReadData(long offset, int size)
169         {
170             file.Seek(offset, SeekOrigin.Begin);
171             this.Log(LogLevel.Info, "Reading {0} bytes from card finished.", size);
172             return file.ReadBytes(size);
173         }
174 
WriteData(long offset, int size, byte[] data)175         public void WriteData(long offset, int size, byte[] data)
176         {
177             file.Seek(offset, SeekOrigin.Begin);
178             file.Write(data, 0, size);
179             this.Log(LogLevel.Info, "Writing {0} bytes to card finished.", (int)size);
180         }
181 
182         public long CardSize
183         {
184             get;
185             set;
186         }
187 
188         private readonly uint cardAddress = 0xaaaa;
189         private uint[] cardSpecificData, cardIdentification;
190         private bool opAppInitialized, opCodeChecked, lastAppOpCodeNormal;
191         private readonly SerializableStreamView file;
192 
193     }
194 }
195 
196