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