1 // 2 // Copyright (c) 2010-2023 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.Core; 10 using Antmicro.Renode.Logging; 11 using Antmicro.Renode.Core.Structure; 12 13 namespace Antmicro.Renode.Peripherals.SD 14 { 15 public abstract class MMCController : NullRegistrationPointPeripheralContainer<DeprecatedSDCard>, IDisposable 16 { Reset()17 public override void Reset() 18 { 19 RegisteredPeripheral.Reset(); 20 } 21 Dispose()22 public void Dispose() 23 { 24 if(RegisteredPeripheral != null) 25 { 26 RegisteredPeripheral.Dispose(); 27 } 28 } 29 MMCController(IMachine machine)30 protected MMCController(IMachine machine) : base(machine) 31 { 32 this.machine = machine; 33 } 34 ReadFromCard(uint cardOffset, int bytes)35 protected byte[] ReadFromCard(uint cardOffset, int bytes) 36 { 37 return RegisteredPeripheral.ReadData((long)BlockSize * cardOffset, bytes); 38 } 39 WriteToCard(uint cardOffset, byte[] data)40 protected void WriteToCard(uint cardOffset, byte[] data) 41 { 42 RegisteredPeripheral.WriteData((long)BlockSize * cardOffset, data.Length, data); 43 } 44 ExecuteCommand(Commands command, uint args, bool sendInitSequence, bool dataTransfer)45 protected uint[] ExecuteCommand(Commands command, uint args, bool sendInitSequence, bool dataTransfer) 46 { 47 var response = new uint[4]; 48 if(RegisteredPeripheral == null) 49 { 50 return response; 51 } 52 53 switch(command) 54 { 55 case Commands.GoIdleState: 56 if(sendInitSequence) 57 { 58 response[0] = RegisteredPeripheral.GoIdleState(); 59 } 60 break; 61 case Commands.SendOpCond: 62 case Commands.IoSendOpCond: 63 response[0] = RegisteredPeripheral.SendOpCond(); 64 break; 65 case Commands.SendStatus: 66 response[0] = RegisteredPeripheral.SendStatus(dataTransfer); 67 break; 68 case Commands.SendSdConfiguration: 69 SendSdConfigurationValue(); 70 break; 71 case Commands.SetRelativeAddress: 72 response[0] = RegisteredPeripheral.SetRelativeAddress(); 73 break; 74 case Commands.SelectDeselectCard: 75 response[0] = RegisteredPeripheral.SelectDeselectCard(); 76 break; 77 case Commands.SendExtendedCardSpecificData: 78 response[0] = RegisteredPeripheral.SendExtendedCardSpecificData(); 79 break; 80 case Commands.SendCardSpecificData: 81 response = RegisteredPeripheral.SendCardSpecificData(); 82 break; 83 case Commands.AllSendCid: 84 return RegisteredPeripheral.AllSendCardIdentification(); 85 case Commands.AppCommand: 86 response[0] = RegisteredPeripheral.AppCommand(args); 87 break; 88 case Commands.Switch: 89 response[0] = RegisteredPeripheral.Switch(); 90 break; 91 case Commands.MmcSendAppOpCode: 92 response[0] = RegisteredPeripheral.SendAppOpCode(args); 93 break; 94 case Commands.ReadMultipleBlocks: 95 TransferDataFromCard(args, ByteCount); 96 break; 97 case Commands.ReadSingleBlock: 98 TransferDataFromCard(args, BlockSize); 99 break; 100 case Commands.WriteMultipleBlocks: 101 TransferDataToCard(args, ByteCount); 102 break; 103 default: 104 this.Log(LogLevel.Warning, "Unhandled MMC command: 0x{0:X} with args 0x{1:X}", command, args); 105 break; 106 } 107 return response; 108 } 109 SendSdConfigurationValue()110 protected abstract void SendSdConfigurationValue(); TransferDataToCard(uint cardOffset, int bytes)111 protected abstract void TransferDataToCard(uint cardOffset, int bytes); TransferDataFromCard(uint cardOffset, int bytes)112 protected abstract void TransferDataFromCard(uint cardOffset, int bytes); 113 114 protected int BlockSize, ByteCount; 115 116 protected readonly IMachine machine; 117 118 protected enum Commands 119 { 120 GoIdleState = 0x0, 121 SendOpCond = 0x1, 122 AllSendCid = 0x2, 123 SetRelativeAddress = 0x3, 124 SetDsr = 0x4, 125 IoSendOpCond = 0x05, 126 Switch = 0x6, 127 SelectDeselectCard = 0x7, 128 SendExtendedCardSpecificData = 0x8, 129 SendCardSpecificData = 0x9, 130 SendCardIdentification = 0xa, 131 ReadDataUntilStop = 0xb, 132 StopTransmission = 0xc, 133 SendStatus = 0xd, 134 BusTestRead = 0xe, 135 GoInactiveState = 0xf, 136 SetBlockLength = 0x10, 137 ReadSingleBlock = 0x11, 138 ReadMultipleBlocks = 0x12, 139 BusTestWrite = 0x13, 140 WriteDataUntilStop = 0x14, 141 SetBlockCount = 0x17, 142 WriteBlock = 0x18, 143 WriteMultipleBlocks = 0x19, 144 ProgramCardIdentification = 0x1a, 145 ProgramCardSpecificData = 0x1b, 146 SetWriteProtection = 0x1c, 147 ClearWriteProtection = 0x1d, 148 SendWriteProtection = 0x1e, 149 EraseGroupStart = 0x23, 150 EraseGroupEnd = 0x24, 151 Erase = 0x26, 152 FastIo = 0x27, 153 GoIrqState = 0x28, 154 MmcSendAppOpCode = 0x29, 155 LockUnlock = 0x2a, 156 SendSdConfiguration = 0x33, 157 IoRwDirect = 0x34, 158 IoRwExtended = 0x35, 159 AppCommand = 0x37, 160 GenCommand = 0x38, 161 } 162 } 163 } 164