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.Core; 10 using Antmicro.Renode.Logging; 11 using Antmicro.Renode.Peripherals.Bus; 12 using Antmicro.Renode.Peripherals; 13 using Antmicro.Renode.Utilities; 14 using System.Threading; 15 16 namespace Antmicro.Renode.Peripherals.DMA 17 { 18 public class OmapDma : IDoubleWordPeripheral 19 { OmapDma()20 public OmapDma () 21 { 22 channels = new Channel[32]; 23 for(int i=0;i<32;i++) 24 { 25 channels[i] = new Channel(); 26 channels[i].InterruptControl = (1u<<13) | (1u<<10) | (1u<<9); 27 } 28 IRQ = new GPIO(); 29 } 30 31 public GPIO IRQ {get; private set;} 32 33 #region IDoubleWordPeripheral implementation ReadDoubleWord(long offset)34 public uint ReadDoubleWord (long offset) 35 { 36 uint index; 37 38 if( (offset >= (long)InternalRegister.IRQStatusLinej) && (offset < (long)InternalRegister.IRQEnableLinej) ) 39 { 40 index = getIndex(offset,(uint)InternalRegister.IRQStatusLinej); 41 return IRQStatus[index]; 42 } 43 if( (offset >= (long)InternalRegister.IRQEnableLinej) && (offset < (long)InternalRegister.SystemStatus) ) 44 { 45 index = getIndex(offset,(uint)InternalRegister.IRQEnableLinej); 46 return IRQEnable[index]; 47 } 48 49 if(offset >= (long)InternalRegister.ChannelsRegisters) 50 { 51 index = getChannelIndex(offset); 52 uint channelOffset = getChannelOffset(offset, index); 53 54 switch ((Channel.Offset)channelOffset) 55 { 56 case Channel.Offset.Control: 57 return channels[index].Control; 58 case Channel.Offset.CurrentActiveDescriptor: 59 return channels[index].CurrentActiveDescriptor; 60 case Channel.Offset.CurrentTransferedElementNumber: 61 return channels[index].CurrentTransferedElementNumber; 62 case Channel.Offset.CurrentTransferedFrameNumber: 63 return channels[index].CurrentTransferedFrameNumber; 64 case Channel.Offset.DestinationAddress: 65 return channels[index].DestinationAddress; 66 case Channel.Offset.DestinationAddressValue: 67 return channels[index].DestinationAddressValue; 68 case Channel.Offset.DestinationElementIndex: 69 return channels[index].DestinationElementIndex; 70 case Channel.Offset.DestinationFrameIndex: 71 return channels[index].DestinationFrameIndex; 72 case Channel.Offset.ElementNumber: 73 return channels[index].ElementNumber; 74 case Channel.Offset.FrameNumber: 75 return channels[index].FrameNumber; 76 case Channel.Offset.InterruptControl: 77 return channels[index].InterruptControl; 78 case Channel.Offset.LinkControl: 79 return channels[index].LinkControl; 80 case Channel.Offset.LinkListParameters: 81 return channels[index].LinkListParameters; 82 case Channel.Offset.NextDescriptorPointer: 83 return channels[index].NextDescriptorPointer; 84 case Channel.Offset.SourceAddress: 85 return channels[index].SourceAddress; 86 case Channel.Offset.SourceDestinationParameters: 87 return channels[index].SourceDestinationParameters; 88 case Channel.Offset.SourceElementIndex: 89 return channels[index].SourceElementIndex; 90 case Channel.Offset.SourceFrameIndex: 91 return channels[index].SourceFrameIndex; 92 case Channel.Offset.SourceStartAddress: 93 return channels[index].SourceStartAddress; 94 case Channel.Offset.StatusRegister: 95 return channels[index].StatusRegister; 96 } 97 } 98 99 switch ((InternalRegister)offset) 100 { 101 case InternalRegister.Revision: 102 return revision; 103 case InternalRegister.SystemStatus: 104 return systemStatus; 105 case InternalRegister.SystemConfiguration: 106 return systemConfiguration; 107 case InternalRegister.Capabilities0: 108 return capabilities0; 109 case InternalRegister.Capabilities2: 110 return capabilities2; 111 case InternalRegister.Capabilities3: 112 return capabilities3; 113 case InternalRegister.Capabilities4: 114 return capabilities4; 115 default: 116 this.LogUnhandledRead(offset); 117 return 0; 118 } 119 } 120 WriteDoubleWord(long offset, uint value)121 public void WriteDoubleWord (long offset, uint value) 122 { 123 uint index; 124 if(value != 0) 125 { 126 this.Log(LogLevel.Info,"dummy"); 127 } 128 129 130 if( (offset >= (long)InternalRegister.IRQStatusLinej) && (offset < (long)InternalRegister.IRQEnableLinej) ) 131 { 132 index = getIndex(offset,(uint)InternalRegister.IRQStatusLinej); 133 IRQStatus[index] = value; 134 } 135 if( (offset >= (long)InternalRegister.IRQEnableLinej) && (offset < (long)InternalRegister.SystemConfiguration) ) 136 { 137 index = getIndex(offset,(uint)InternalRegister.IRQEnableLinej); 138 IRQEnable[index] = value; 139 } 140 141 if(offset >= (long)InternalRegister.ChannelsRegisters) 142 { 143 index = getChannelIndex(offset); 144 uint channelOffset = getChannelOffset(offset, index); 145 146 switch ((Channel.Offset)channelOffset) 147 { 148 case Channel.Offset.Control: 149 channels[index].Control = value; 150 break; 151 case Channel.Offset.CurrentActiveDescriptor: 152 channels[index].CurrentActiveDescriptor = value; 153 break; 154 case Channel.Offset.CurrentTransferedElementNumber: 155 channels[index].CurrentTransferedElementNumber = value; 156 break; 157 case Channel.Offset.CurrentTransferedFrameNumber: 158 channels[index].CurrentTransferedFrameNumber = value; 159 break; 160 case Channel.Offset.DestinationAddress: 161 channels[index].DestinationAddress = value; 162 break; 163 case Channel.Offset.DestinationAddressValue: 164 channels[index].DestinationAddressValue = value; 165 break; 166 case Channel.Offset.DestinationElementIndex: 167 channels[index].DestinationElementIndex = value; 168 break; 169 case Channel.Offset.DestinationFrameIndex: 170 channels[index].DestinationFrameIndex = value; 171 break; 172 case Channel.Offset.ElementNumber: 173 channels[index].ElementNumber = value; 174 break; 175 case Channel.Offset.FrameNumber: 176 channels[index].FrameNumber = value; 177 break; 178 case Channel.Offset.InterruptControl: 179 channels[index].InterruptControl = value; 180 break; 181 case Channel.Offset.LinkControl: 182 channels[index].LinkControl = value; 183 break; 184 case Channel.Offset.LinkListParameters: 185 channels[index].LinkListParameters = value; 186 break; 187 case Channel.Offset.NextDescriptorPointer: 188 channels[index].NextDescriptorPointer = value; 189 break; 190 case Channel.Offset.SourceAddress: 191 channels[index].SourceAddress = value; 192 break; 193 case Channel.Offset.SourceDestinationParameters: 194 channels[index].SourceDestinationParameters = value; 195 break; 196 case Channel.Offset.SourceElementIndex: 197 channels[index].SourceElementIndex = value; 198 break; 199 case Channel.Offset.SourceFrameIndex: 200 channels[index].SourceFrameIndex = value; 201 break; 202 case Channel.Offset.SourceStartAddress: 203 channels[index].SourceStartAddress = value; 204 break; 205 case Channel.Offset.StatusRegister: 206 channels[index].StatusRegister = value; 207 break; 208 } 209 } 210 211 switch ((InternalRegister) offset) 212 { 213 case InternalRegister.SystemConfiguration: 214 systemConfiguration=value; 215 break; 216 case InternalRegister.Capabilities0: 217 capabilities0 = value; 218 break; 219 case InternalRegister.Capabilities4: 220 capabilities4 = value; 221 break; 222 default: 223 this.LogUnhandledWrite(offset, value); 224 break; 225 } 226 } 227 #endregion 228 Reset()229 public void Reset () 230 { 231 throw new NotImplementedException (); 232 } 233 getIndex(long offset, uint regBaseAddress)234 private uint getIndex(long offset, uint regBaseAddress) 235 { 236 return (uint)((offset - regBaseAddress)/0x04u); 237 } 238 239 getChannelIndex(long offset)240 private uint getChannelIndex(long offset) 241 { 242 return (uint)((offset - (uint)InternalRegister.ChannelsRegisters)/(uint)InternalRegister.ChannelRegisterLength); 243 } 244 getChannelOffset(long offset, uint index)245 private uint getChannelOffset(long offset, uint index) 246 { 247 return (uint)(offset - (uint)InternalRegister.ChannelsRegisters - 0x60u * index); 248 } 249 250 private uint[] IRQStatus = new uint[4]; 251 private uint[] IRQEnable = new uint[4]; 252 private struct Channel 253 { 254 public uint Control; 255 public uint LinkControl; 256 public uint InterruptControl; //TODO: init (1u<<13) | (1u<<10) | (1u<<9) 257 public uint StatusRegister; 258 public uint SourceDestinationParameters; 259 public uint ElementNumber; 260 public uint FrameNumber; 261 public uint SourceStartAddress; 262 public uint DestinationAddress; 263 public uint SourceElementIndex; 264 public uint SourceFrameIndex; 265 public uint DestinationElementIndex; 266 public uint DestinationFrameIndex; 267 public uint SourceAddress; 268 public uint DestinationAddressValue; 269 public uint CurrentTransferedElementNumber; 270 public uint CurrentTransferedFrameNumber; 271 public uint LinkListParameters; 272 public uint NextDescriptorPointer; 273 public uint CurrentActiveDescriptor; 274 275 public enum Offset:uint//register offsets in single channel register set 276 { 277 Control = 0x00, 278 LinkControl = 0x04, 279 InterruptControl = 0x08, //TODO: init (1u<<13) | (1u<<10) | (1u<<9) 280 StatusRegister = 0x0C, 281 SourceDestinationParameters = 0x10, 282 ElementNumber = 0x14, 283 FrameNumber = 0x18, 284 SourceStartAddress = 0x1C, 285 DestinationAddress = 0x20, 286 SourceElementIndex = 0x24, 287 SourceFrameIndex = 0x28, 288 DestinationElementIndex = 0x2C, 289 DestinationFrameIndex = 0x30, 290 SourceAddress = 0x34, 291 DestinationAddressValue = 0x38, 292 CurrentTransferedElementNumber = 0x3C, 293 CurrentTransferedFrameNumber = 0x40, 294 LinkListParameters = 0x50, 295 NextDescriptorPointer = 0x54, 296 CurrentActiveDescriptor = 0x5C 297 } 298 } 299 300 301 private Channel[] channels; 302 private uint capabilities0 = (1u<<20)|(1u<<19)|(1u<<18); 303 private uint capabilities4 = 0x5dfe; 304 private uint systemConfiguration = 0; 305 306 // RO 307 private const uint revision = 0;//Revision 0.0 (Highter revision numbers reserved for future use) 308 private const uint systemStatus = 1;//Reset done 309 private const uint capabilities2 = 0x1f; 310 private const uint capabilities3 = 0xf3; 311 312 private enum InternalRegister:uint 313 { 314 Revision = 0x00, 315 IRQStatusLinej = 0x08,//j = 0 .. 3 (each line register is 0x04 long) 316 IRQEnableLinej = 0x18,//j = 0 .. 3 (each line register is 0x04 long) 317 SystemStatus = 0x28, 318 SystemConfiguration = 0x2c, 319 Capabilities0 = 0x64, 320 Capabilities2 = 0x6c, 321 Capabilities3 = 0x70, 322 Capabilities4 = 0x78, 323 ChannelsRegisters = 0x80, 324 ChannelRegisterLength = 0x60 325 } 326 } 327 } 328 329