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.Core.Structure; 11 using Antmicro.Renode.Logging; 12 using Antmicro.Renode.Peripherals.Bus; 13 using Antmicro.Renode.Peripherals.PCI; 14 using System.Collections.Generic; 15 using System.Linq; 16 using Antmicro.Renode.UserInterface; 17 18 namespace Antmicro.Renode.Peripherals.USBDeprecated 19 { 20 [Icon("usb")] 21 public class ISP1761 : IDoubleWordPeripheral, IPeripheralRegister<IUSBHub, USBRegistrationPoint>, IPeripheralContainer<IUSBPeripheral, USBRegistrationPoint>, IPCIPeripheral 22 { 23 private readonly IMachine machine; 24 protected IUSBPeripheral activeDevice; 25 protected IUSBPeripheral defaultDevice; 26 GetPCIInfo()27 public PCIInfo GetPCIInfo() 28 { 29 return pci_info; 30 } 31 Register(IUSBHub peripheral, USBRegistrationPoint registrationInfo)32 public void Register(IUSBHub peripheral, USBRegistrationPoint registrationInfo) 33 { 34 AttachHUBDevice(peripheral, registrationInfo.Address.Value); 35 registerHub(peripheral); 36 machine.RegisterAsAChildOf(this, peripheral, registrationInfo); 37 defaultDevice = peripheral; 38 return; 39 } 40 Unregister(IUSBHub peripheral)41 public void Unregister(IUSBHub peripheral) 42 { 43 byte port = registeredDevices.FirstOrDefault(x => x.Value == peripheral).Key; 44 DetachDevice(port); 45 machine.UnregisterAsAChildOf(this, peripheral); 46 registeredDevices.Remove(port); 47 registeredHubs.Remove(port); 48 } 49 ISP1761(IMachine machine)50 public ISP1761(IMachine machine) 51 { 52 // pci-specific info. 53 pci_info = new PCIInfo(0x5406, 0x10b5, 0x9054, 0x10b5, 0x680); 54 pci_info.BAR_len[0] = 0x10000; 55 pci_info.BAR_len[3] = 0x10000; 56 57 for(int i = 0; i<32; i++) 58 { 59 ptd[i] = new PTD(); 60 ptdi[i] = new PTD(); 61 62 } 63 intDoneMap = 0x00000000; 64 intSkipMap = 0xFFFFFFFF; 65 atlSkipMap = 0xFFFFFFFF; 66 atlDoneMap = 0x00000000; 67 atlIRQMaskOR = 0x0000000; 68 swReset = 0x00000000; 69 memoryReg = 0x0000000; 70 this.machine = machine; 71 interr = 0; 72 IRQ = new GPIO(); 73 this.machine = machine; 74 registeredDevices = new Dictionary<byte, IUSBPeripheral>(); 75 adressedDevices = new Dictionary<byte, IUSBPeripheral>(); 76 registeredHubs = new Dictionary<byte, IUSBHub>(); 77 78 portSc = new PortStatusAndControlRegister [1]; //port status control 79 for(int i = 0; i<portSc.Length; i++) 80 { 81 portSc[i] = new PortStatusAndControlRegister(); 82 83 } 84 setupData = new USBSetupPacket(); 85 86 softReset();//soft reset must be done before attaching devices 87 88 } 89 Active(IUSBPeripheral periph)90 public void Active(IUSBPeripheral periph) 91 { 92 activeDevice = periph; 93 } 94 Reset()95 public void Reset() 96 { 97 softReset(); 98 activeDevice = defaultDevice; 99 } 100 101 public GPIO IRQ { get; private set; } 102 Register(IUSBPeripheral peripheral, USBRegistrationPoint registrationInfo)103 public void Register(IUSBPeripheral peripheral, USBRegistrationPoint registrationInfo) 104 { 105 AttachHUBDevice(peripheral, registrationInfo.Address.Value); 106 machine.RegisterAsAChildOf(this, peripheral, registrationInfo); 107 defaultDevice = peripheral; 108 } 109 Unregister(IUSBPeripheral peripheral)110 public void Unregister(IUSBPeripheral peripheral) 111 { 112 byte port = registeredDevices.FirstOrDefault(x => x.Value == peripheral).Key; 113 DetachDevice(port); 114 machine.UnregisterAsAChildOf(this, peripheral); 115 registeredDevices.Remove(port); 116 registeredHubs.Remove(port); 117 } 118 GetRegistrationPoints(IUSBPeripheral peripheral)119 public IEnumerable<USBRegistrationPoint> GetRegistrationPoints(IUSBPeripheral peripheral) 120 { 121 throw new System.NotImplementedException(); 122 } 123 124 public IEnumerable<IRegistered<IUSBPeripheral, USBRegistrationPoint>> Children 125 { 126 get 127 { 128 throw new System.NotImplementedException(); 129 } 130 } 131 132 private bool firstReset = true; 133 Done(int p)134 public void Done(int p) 135 { 136 atlDoneMap |= (uint)(1 << p); 137 atlIRQMaskOR |= (uint)(1 << p); 138 } 139 WriteDoubleWordPCI(uint bar, long offset, uint value)140 public void WriteDoubleWordPCI(uint bar, long offset, uint value) 141 { 142 if(bar == 3) 143 WriteDoubleWord(offset, value); 144 return; 145 } 146 ReadDoubleWordPCI(uint bar, long offset)147 public uint ReadDoubleWordPCI(uint bar, long offset) 148 { 149 if(bar == 3) 150 return ReadDoubleWord(offset); 151 return 0; 152 } 153 ReadDoubleWord(long address)154 public uint ReadDoubleWord(long address) 155 { 156 //this.Log(LogType.Warning, "Read from offset 0x{0:X}", address); 157 158 if(address >= (uint)0x64 && address < (uint)0x130) 159 { 160 uint portNumber = (uint)(address - (uint)Offset.PortStatusControl) / 4u; 161 162 return portSc[portNumber].getValue(); 163 164 } 165 else if(address >= (uint)0x800 && address < (uint)0xbff) 166 { 167 168 //this.Log(LogType.Warning, "READ PTD {0} reg {1}", (address - 0x800) / 32, ((address - 0x800) / 4) % 8); 169 if(((address - 0x800) / 4) % 8 == 0) 170 { 171 // this.Log(LogType.Warning, "READ VAL 0{0:X}",ptd[(address - 0x800) / 32].DW0); 172 return ptdi[(address - 0x800) / 32].DW0; 173 } 174 if(((address - 0x800) / 4) % 8 == 1) 175 { //this.Log(LogType.Warning, "READ VAL 0{0:X}",ptd[(address - 0x800) / 32].DW1); 176 return ptdi[(address - 0x800) / 32].DW1; 177 } 178 if(((address - 0x800) / 4) % 8 == 2) 179 { //this.Log(LogType.Warning, "READ VAL 0{0:X}",ptd[(address - 0x800) / 32].DW2); 180 return ptdi[(address - 0x800) / 32].DW2; 181 } 182 if(((address - 0x800) / 4) % 8 == 3) 183 { //this.Log(LogType.Warning, "READ VAL 0{0:X}",ptd[(address - 0x800) / 32].DW3); 184 return ptdi[(address - 0x800) / 32].DW3; 185 } 186 if(((address - 0x800) / 4) % 8 == 4) 187 { //this.Log(LogType.Warning, "READ VAL 0{0:X}",ptd[(address - 0x800) / 32].DW4); 188 return ptdi[(address - 0x800) / 32].DW4; 189 } 190 if(((address - 0x800) / 4) % 8 == 5) 191 { //this.Log(LogType.Warning, "READ VAL 0{0:X}",ptd[(address - 0x800) / 32].DW5); 192 return ptdi[(address - 0x800) / 32].DW5; 193 } 194 if(((address - 0x800) / 4) % 8 == 6) 195 { //this.Log(LogType.Warning, "READ VAL 0{0:X}",ptd[(address - 0x800) / 32].DW6); 196 return ptdi[(address - 0x800) / 32].DW6; 197 } 198 if(((address - 0x800) / 4) % 8 == 7) 199 { //this.Log(LogType.Warning, "READ VAL 0{0:X}",ptd[(address - 0x800) / 32].DW7); 200 return ptdi[(address - 0x800) / 32].DW7; 201 } 202 } 203 else 204 /* Read QH registers */ if(address >= (uint)0xc00 && address < (uint)0x1000) 205 { 206 //this.Log(LogType.Warning, "READ PTD {0} reg {1}", (address - 0xc00) / 32, ((address - 0xc00) / 4) % 8); 207 if(((address - 0xc00) / 4) % 8 == 0) 208 { 209 // this.Log(LogType.Warning, "READ VAL 0{0:X}",ptd[(address - 0xc00) / 32].DW0); 210 return ptd[(address - 0xc00) / 32].DW0; 211 } 212 if(((address - 0xc00) / 4) % 8 == 1) 213 { //this.Log(LogType.Warning, "READ VAL 0{0:X}",ptd[(address - 0xc00) / 32].DW1); 214 return ptd[(address - 0xc00) / 32].DW1; 215 } 216 if(((address - 0xc00) / 4) % 8 == 2) 217 { //this.Log(LogType.Warning, "READ VAL 0{0:X}",ptd[(address - 0xc00) / 32].DW2); 218 return ptd[(address - 0xc00) / 32].DW2; 219 } 220 if(((address - 0xc00) / 4) % 8 == 3) 221 { //this.Log(LogType.Warning, "READ VAL 0{0:X}",ptd[(address - 0xc00) / 32].DW3); 222 return ptd[(address - 0xc00) / 32].DW3; 223 } 224 if(((address - 0xc00) / 4) % 8 == 4) 225 { //this.Log(LogType.Warning, "READ VAL 0{0:X}",ptd[(address - 0xc00) / 32].DW4); 226 return ptd[(address - 0xc00) / 32].DW4; 227 } 228 if(((address - 0xc00) / 4) % 8 == 5) 229 { //this.Log(LogType.Warning, "READ VAL 0{0:X}",ptd[(address - 0xc00) / 32].DW5); 230 return ptd[(address - 0xc00) / 32].DW5; 231 } 232 if(((address - 0xc00) / 4) % 8 == 6) 233 { //this.Log(LogType.Warning, "READ VAL 0{0:X}",ptd[(address - 0xc00) / 32].DW6); 234 return ptd[(address - 0xc00) / 32].DW6; 235 } 236 if(((address - 0xc00) / 4) % 8 == 7) 237 { //this.Log(LogType.Warning, "READ VAL 0{0:X}",ptd[(address - 0xc00) / 32].DW7); 238 return ptd[(address - 0xc00) / 32].DW7; 239 } 240 } 241 else 242 /* Read from memory area*/ if(address >= (uint)0x1000 && address <= (uint)0xffff) 243 { 244 //this.Log(LogType.Warning, "Read payLoad 0{0:X}", address); 245 return (uint)BitConverter.ToUInt32(payLoad, (int)((address))); 246 } 247 else 248 { 249 uint tDM = 0; 250 switch((Offset)address) 251 { 252 case Offset.CapabilityLength: 253 return capBase; 254 255 case Offset.StructuralParameters: 256 return hCSParams; 257 258 case Offset.CapabilityParameters: 259 return hCCParams; 260 261 case Offset.CompanionPortRouting1: 262 return hscpPortRoute[0]; 263 264 case Offset.CompanionPortRouting2: 265 return hscpPortRoute[1]; 266 267 case Offset.UsbCommand: 268 return usbCmd; 269 270 case Offset.UsbStatus: 271 return usbSts; 272 273 case Offset.UsbFrameIndex: 274 return usbFrIndex; 275 276 case Offset.AsyncListAddress: 277 return asyncListAddress; 278 279 case Offset.ConfiguredFlag: 280 return configFlag; 281 282 case Offset.UsbInterruptEnable: 283 return interruptEnableRegister.getRegister(); 284 285 case (Offset)Offset.INTPTDDoneMap: 286 tDM = intDoneMap; 287 intDoneMap = 0x0; 288 return tDM; 289 case (Offset)Offset.INTPTDSkipMap: 290 return intSkipMap; 291 case Offset.INTPTDLastPTD: 292 return intLastPTD; 293 294 case (Offset)0x330: 295 return atlIRQMaskOR; 296 case (Offset)Offset.Memory: 297 return memoryReg; 298 case (Offset)Offset.ATLPTDDoneMap: 299 tDM = atlDoneMap; 300 atlDoneMap = 0x0; 301 return tDM; 302 case (Offset)Offset.ATLPTDSkipMap: 303 return atlSkipMap; 304 case (Offset)Offset.ChipID: 305 return 0x00011761; 306 case (Offset)Offset.Scratch: 307 return scratch; 308 case Offset.ATLPTDLastPTD: 309 return atlLastPTD; 310 case (Offset)Offset.Interrupt: 311 return (uint)interr;//0xffffffff; 312 case (Offset)Offset.SWReset: 313 return swReset; 314 default: 315 this.LogUnhandledRead(address); 316 break; 317 } 318 } 319 return 0; 320 } 321 322 private Dictionary <byte,IUSBPeripheral> registeredDevices; 323 private Dictionary <byte,IUSBHub> registeredHubs; 324 private Dictionary <byte,IUSBPeripheral> adressedDevices; 325 DoneInt(int p)326 public void DoneInt(int p) 327 { 328 intDoneMap |= (uint)(1 << p); 329 intIRQMaskOR |= (uint)(1 << p); 330 } 331 regHub(IUSBHub hub)332 public void regHub(IUSBHub hub) 333 { 334 registeredHubs.Add((byte)(registeredHubs.Count() + 1), hub); 335 } 336 registerHub(IUSBHub hub)337 public void registerHub(IUSBHub hub) 338 { 339 regHub(hub); 340 activeDevice = hub; 341 hub.RegisterHub += new Action<IUSBHub>(regHub); 342 hub.Connected += new Action<uint>(AttachHUBDevice); 343 hub.Disconnected += new Action<uint,uint>(DetachHUBDevice); 344 hub.ActiveDevice += new Action<IUSBPeripheral>(Active); 345 } 346 AttachHUBDevice(uint addr)347 public void AttachHUBDevice(uint addr) 348 { 349 PTDheader PTDh = new PTDheader(); 350 for(int p=0; p<32; p++) 351 // int p=0; 352 //int p=0; 353 //if(atlSkipMap == 0xFFFFFFFE) 354 if(((1 << p) ^ (intSkipMap & (1 << p))) != 0) 355 { 356 if((1 << p) == intLastPTD) 357 { 358 break; 359 } 360 PTDh.V = (ptdi[p].DW0) & 0x1; 361 PTDh.NrBytesToTransfer = (ptdi[p].DW0 >> 3) & 0x7fff; 362 PTDh.MaxPacketLength = (ptdi[p].DW0 >> 18) & 0x7ff; 363 PTDh.Mult = (ptdi[p].DW0 >> 29) & 0x2; 364 PTDh.EndPt = (((ptdi[p].DW1) & 0x7) << 1) | (ptdi[p].DW0 >> 31); 365 PTDh.DeviceAddress = (byte)((ptdi[p].DW1 >> 3) & 0x7f); 366 PTDh.Token = (ptdi[p].DW1 >> 10) & 0x3; 367 PTDh.EPType = (ptdi[p].DW1 >> 12) & 0x3; 368 PTDh.S = (ptdi[p].DW1 >> 14) & 0x1; 369 PTDh.SE = (ptdi[p].DW1 >> 16) & 0x3; 370 PTDh.PortNumber = (byte)((ptdi[p].DW1 >> 18) & 0x7f); 371 PTDh.HubAddress = (byte)((ptdi[p].DW1 >> 25) & 0x7f); 372 PTDh.DataStartAddress = (((ptdi[p].DW2 >> 8) & 0xffff) << 3) + 0x400; 373 PTDh.RL = (ptdi[p].DW2 >> 25) & 0xf; 374 PTDh.NrBytesTransferred = (ptdi[p].DW3) & 0x7fff; 375 PTDh.NakCnt = (ptdi[p].DW3 >> 19) & 0xf; 376 PTDh.Cerr = (ptdi[p].DW3 >> 23) & 0x3; 377 PTDh.DT = (ptdi[p].DW3 >> 25) & 0x1; 378 PTDh.SC = (ptdi[p].DW3 >> 27) & 0x1; 379 PTDh.X = (ptdi[p].DW3 >> 28) & 0x1; 380 PTDh.B = (ptdi[p].DW3 >> 29) & 0x1; 381 PTDh.H = (ptdi[p].DW3 >> 30) & 0x1; 382 PTDh.A = (ptdi[p].DW3 >> 31) & 0x1; 383 PTDh.NextPTDPointer = (ptdi[p].DW4) & 0x1F; 384 PTDh.J = (ptdi[p].DW4 >> 5) & 0x1; 385 if(addr == PTDh.DeviceAddress) 386 { 387 388 if(PTDh.V != 0) 389 { 390 /* Process Packet */ 391 ProcessPacketInt(PTDh); 392 /* Set packet done bits */ 393 //if (PTDh.V==0) 394 { 395 //PTDh.H=1; 396 ptdi[p].DW0 = ptdi[p].DW0 & 0xfffffffe; 397 ptdi[p].DW3 = (uint)(((ptdi[p].DW3 | ((((0 >> 3) & 0x7fff) + PTDh.NrBytesTransferred) & 0x7fff) << 0) & 0x7fffffff)); 398 ptdi[p].DW3 = ptdi[p].DW3 | (PTDh.B << 29); 399 ptdi[p].DW3 = ptdi[p].DW3 | (PTDh.H << 30); 400 ptdi[p].DW4 = ptdi[p].DW4 & 0xfffffffe; 401 DoneInt(p); 402 403 if((interruptEnableRegister.OnAsyncAdvanceEnable == true) & (interruptEnableRegister.Enable == true)) 404 { 405 usbSts |= (uint)InterruptMask.USBInterrupt | (uint)InterruptMask.InterruptOnAsyncAdvance; //raise flags in status register 406 interr |= 1 << 7; 407 IRQ.Set(true); //raise interrupt 408 } 409 } 410 } 411 } 412 } 413 } 414 addressDevice(IUSBPeripheral device, byte address)415 private void addressDevice(IUSBPeripheral device, byte address) 416 { 417 418 if(!adressedDevices.ContainsKey(address))//XXX: Linux hack 419 { 420 adressedDevices.Add(address, device); 421 } 422 } 423 findDevice(byte deviceAddress)424 private IUSBPeripheral findDevice(byte deviceAddress) 425 { 426 if(registeredHubs.Count() > 0) 427 { 428 if(adressedDevices.ContainsKey(deviceAddress)) 429 { 430 IUSBPeripheral device = adressedDevices[deviceAddress]; 431 return device; 432 } 433 else 434 { 435 return null; 436 } 437 } 438 return null; 439 } 440 softReset()441 public void softReset() 442 { 443 444 adressedDevices = new Dictionary<byte, IUSBPeripheral>(); 445 446 hCSParams = (nCC & 0x0f) << 12 | (nPCC & 0x0f) << 8 | ((uint)portSc.Length & 0xf) << 0; 447 //TODO: manage variable amount of ports 448 for(int i=0; i < portSc.Length; i++) 449 { 450 portSc[i].setValue(0x00001000); 451 portSc[i].powerUp(); 452 453 if(firstReset) 454 { 455 PortStatusAndControlRegisterChanges change = portSc[i].Attach(); 456 firstReset = false; 457 //} 458 459 if(change.ConnectChange == true) 460 { 461 usbSts |= (uint)InterruptMask.PortChange; 462 } 463 464 if((interruptEnableRegister.Enable == true) && (interruptEnableRegister.PortChangeEnable == true)) 465 { 466 usbSts |= (uint)InterruptMask.USBInterrupt | (uint)InterruptMask.PortChange; //raise flags in status register 467 // interr|=1<<8; 468 interr |= 1 << 8; 469 IRQ.Set(true); //raise interrupt 470 } 471 } 472 } 473 //interrupts 474 475 } 476 WriteDoubleWord(long address, uint value)477 public void WriteDoubleWord(long address, uint value) 478 { 479 if(address >= (uint)0x64 && address < (uint)0x130) 480 { 481 uint portNumber = (uint)(address - (uint)Offset.PortStatusControl) / 4; 482 483 PortStatusAndControlRegisterChanges change = portSc[portNumber].setValue(value); 484 if(change.ConnectChange == true) 485 { 486 usbSts |= (uint)InterruptMask.PortChange; 487 } 488 489 if((interruptEnableRegister.Enable == true) && (interruptEnableRegister.PortChangeEnable == true)) 490 { 491 492 usbSts |= (uint)InterruptMask.USBInterrupt | (uint)InterruptMask.PortChange; //raise flags in status register 493 interr |= 1 << 8; 494 IRQ.Set(true); //raise interrupt 495 } 496 } 497 else if(address >= (uint)0x800 && address < (uint)0xbff) 498 { 499 if(((address - 0x800) / 4) % 8 == 0) 500 { 501 ptdi[(address - 0x800) / 32].DW0 = value; 502 503 PTDheader PTDh = new PTDheader(); 504 PTDh.V = (ptdi[(address - 0x800) / 32].DW0) & 0x1; 505 PTDh.NrBytesToTransfer = (ptdi[(address - 0x800) / 32].DW0 >> 3) & 0x7fff; 506 PTDh.MaxPacketLength = (ptdi[(address - 0x800) / 32].DW0 >> 18) & 0x7ff; 507 PTDh.Mult = (ptdi[(address - 0x800) / 32].DW0 >> 29) & 0x2; 508 PTDh.EndPt = (((ptdi[(address - 0x800) / 32].DW1) & 0x7) << 1) | (ptdi[(address - 0x800) / 32].DW0 >> 31); 509 PTDh.DeviceAddress = (byte)((ptdi[(address - 0x800) / 32].DW1 >> 3) & 0x7f); 510 PTDh.Token = (ptdi[(address - 0x800) / 32].DW1 >> 10) & 0x3; 511 PTDh.EPType = (ptdi[(address - 0x800) / 32].DW1 >> 12) & 0x3; 512 PTDh.S = (ptdi[(address - 0x800) / 32].DW1 >> 14) & 0x1; 513 PTDh.SE = (ptdi[(address - 0x800) / 32].DW1 >> 16) & 0x3; 514 PTDh.PortNumber = (byte)((ptdi[(address - 0x800) / 32].DW1 >> 18) & 0x7f); 515 PTDh.HubAddress = (byte)((ptdi[(address - 0x800) / 32].DW1 >> 25) & 0x7f); 516 PTDh.DataStartAddress = (ptdi[(address - 0x800) / 32].DW2 >> 8) & 0xffff; 517 PTDh.RL = (ptdi[(address - 0x800) / 32].DW2 >> 25) & 0xf; 518 PTDh.NrBytesTransferred = (ptdi[(address - 0x800) / 32].DW3) & 0x7fff; 519 PTDh.NakCnt = (ptdi[(address - 0x800) / 32].DW3 >> 19) & 0xf; 520 PTDh.Cerr = (ptdi[(address - 0x800) / 32].DW3 >> 23) & 0x3; 521 PTDh.DT = (ptdi[(address - 0x800) / 32].DW3 >> 25) & 0x1; 522 PTDh.SC = (ptdi[(address - 0x800) / 32].DW3 >> 27) & 0x1; 523 PTDh.X = (ptdi[(address - 0x800) / 32].DW3 >> 28) & 0x1; 524 PTDh.B = (ptdi[(address - 0x800) / 32].DW3 >> 29) & 0x1; 525 PTDh.H = (ptdi[(address - 0x800) / 32].DW3 >> 30) & 0x1; 526 PTDh.A = (ptdi[(address - 0x800) / 32].DW3 >> 31) & 0x1; 527 PTDh.NextPTDPointer = (ptdi[(address - 0x800) / 32].DW4) & 0x1F; 528 PTDh.J = (ptdi[(address - 0x800) / 32].DW4 >> 5) & 0x1; 529 if(PTDh.V == 1) 530 { 531 532 { 533 this.Log(LogLevel.Noisy, "REG---------------------------"); 534 this.Log(LogLevel.Noisy, "V=0{0:X}", PTDh.V); 535 this.Log(LogLevel.Noisy, "NrBytesToTransfer=0{0:X}", PTDh.NrBytesToTransfer); 536 this.Log(LogLevel.Noisy, "MaxPacketLength=0{0:X}", PTDh.MaxPacketLength); 537 this.Log(LogLevel.Noisy, "Mult=0{0:X}", PTDh.Mult); 538 this.Log(LogLevel.Noisy, "EndPt=0{0:X}", PTDh.EndPt); 539 this.Log(LogLevel.Noisy, "DeviceAddress=0{0:X}", PTDh.DeviceAddress); 540 this.Log(LogLevel.Noisy, "Token=0{0:X}", PTDh.Token); 541 this.Log(LogLevel.Noisy, "EPType=0{0:X}", PTDh.EPType); 542 this.Log(LogLevel.Noisy, "S=0{0:X}", PTDh.S); 543 this.Log(LogLevel.Noisy, "SE=0{0:X}", PTDh.SE); 544 this.Log(LogLevel.Noisy, "PortNumber=0{0:X}", PTDh.PortNumber); 545 this.Log(LogLevel.Noisy, "HubAddress =0{0:X}", PTDh.HubAddress); 546 this.Log(LogLevel.Noisy, "DataStartAddress=0{0:X}", PTDh.DataStartAddress); 547 this.Log(LogLevel.Noisy, "RL=0{0:X}", PTDh.RL); 548 this.Log(LogLevel.Noisy, "NrBytesTransferred=0{0:X}", PTDh.NrBytesTransferred); 549 this.Log(LogLevel.Noisy, "NakCnt=0{0:X}", PTDh.NakCnt); 550 this.Log(LogLevel.Noisy, "Cerr =0{0:X}", PTDh.Cerr); 551 this.Log(LogLevel.Noisy, "DT=0{0:X}", PTDh.DT); 552 this.Log(LogLevel.Noisy, "SC=0{0:X}", PTDh.SC); 553 this.Log(LogLevel.Noisy, "X=0{0:X}", PTDh.X); 554 this.Log(LogLevel.Noisy, "B=0{0:X}", PTDh.B); 555 this.Log(LogLevel.Noisy, "H =0{0:X}", PTDh.H); 556 this.Log(LogLevel.Noisy, "A=0{0:X}", PTDh.A); 557 this.Log(LogLevel.Noisy, "NextPTDPointer =0{0:X}", PTDh.NextPTDPointer); 558 this.Log(LogLevel.Noisy, "J=0{0:X}", PTDh.J); 559 } 560 ProcessINT(PTDh.DeviceAddress); 561 } 562 } 563 564 if(((address - 0x800) / 4) % 8 == 1) 565 { 566 ptdi[(address - 0x800) / 32].DW1 = value; 567 } 568 if(((address - 0x800) / 4) % 8 == 2) 569 { 570 ptdi[(address - 0x800) / 32].DW2 = value; 571 } 572 if(((address - 0x800) / 4) % 8 == 3) 573 { 574 ptdi[(address - 0x800) / 32].DW3 = value; 575 } 576 if(((address - 0x800) / 4) % 8 == 4) 577 { 578 ptdi[(address - 0x800) / 32].DW4 = value; 579 } 580 if(((address - 0x800) / 4) % 8 == 5) 581 { 582 ptdi[(address - 0x800) / 32].DW5 = value; 583 } 584 if(((address - 0x800) / 4) % 8 == 6) 585 { 586 ptdi[(address - 0x800) / 32].DW6 = value; 587 } 588 if(((address - 0x800) / 4) % 8 == 7) 589 { 590 ptdi[(address - 0x800) / 32].DW7 = value; 591 } 592 593 } 594 else if(address >= (uint)0xc00 && address < (uint)0x1000) 595 { 596 if(((address - 0xc00) / 4) % 8 == 0) 597 { 598 ptd[(address - 0xc00) / 32].DW0 = value; 599 600 PTDheader PTDh = new PTDheader(); 601 PTDh.V = (ptd[(address - 0xc00) / 32].DW0) & 0x1; 602 PTDh.NrBytesToTransfer = (ptd[(address - 0xc00) / 32].DW0 >> 3) & 0x7fff; 603 PTDh.MaxPacketLength = (ptd[(address - 0xc00) / 32].DW0 >> 18) & 0x7ff; 604 PTDh.Mult = (ptd[(address - 0xc00) / 32].DW0 >> 29) & 0x2; 605 PTDh.EndPt = (((ptd[(address - 0xc00) / 32].DW1) & 0x7) << 1) | (ptd[(address - 0xc00) / 32].DW0 >> 31); 606 PTDh.DeviceAddress = (byte)((ptd[(address - 0xc00) / 32].DW1 >> 3) & 0x7f); 607 PTDh.Token = (ptd[(address - 0xc00) / 32].DW1 >> 10) & 0x3; 608 PTDh.EPType = (ptd[(address - 0xc00) / 32].DW1 >> 12) & 0x3; 609 PTDh.S = (ptd[(address - 0xc00) / 32].DW1 >> 14) & 0x1; 610 PTDh.SE = (ptd[(address - 0xc00) / 32].DW1 >> 16) & 0x3; 611 PTDh.PortNumber = (byte)((ptd[(address - 0xc00) / 32].DW1 >> 18) & 0x7f); 612 PTDh.HubAddress = (byte)((ptd[(address - 0xc00) / 32].DW1 >> 25) & 0x7f); 613 PTDh.DataStartAddress = (ptd[(address - 0xc00) / 32].DW2 >> 8) & 0xffff; 614 PTDh.RL = (ptd[(address - 0xc00) / 32].DW2 >> 25) & 0xf; 615 PTDh.NrBytesTransferred = (ptd[(address - 0xc00) / 32].DW3) & 0x7fff; 616 PTDh.NakCnt = (ptd[(address - 0xc00) / 32].DW3 >> 19) & 0xf; 617 PTDh.Cerr = (ptd[(address - 0xc00) / 32].DW3 >> 23) & 0x3; 618 PTDh.DT = (ptd[(address - 0xc00) / 32].DW3 >> 25) & 0x1; 619 PTDh.SC = (ptd[(address - 0xc00) / 32].DW3 >> 27) & 0x1; 620 PTDh.X = (ptd[(address - 0xc00) / 32].DW3 >> 28) & 0x1; 621 PTDh.B = (ptd[(address - 0xc00) / 32].DW3 >> 29) & 0x1; 622 PTDh.H = (ptd[(address - 0xc00) / 32].DW3 >> 30) & 0x1; 623 PTDh.A = (ptd[(address - 0xc00) / 32].DW3 >> 31) & 0x1; 624 PTDh.NextPTDPointer = (ptd[(address - 0xc00) / 32].DW4) & 0x1F; 625 PTDh.J = (ptd[(address - 0xc00) / 32].DW4 >> 5) & 0x1; 626 if(PTDh.V == 1) 627 { 628 629 { 630 this.Log(LogLevel.Noisy, "REG---------------------------"); 631 this.Log(LogLevel.Noisy, "V=0{0:X}", PTDh.V); 632 this.Log(LogLevel.Noisy, "NrBytesToTransfer=0{0:X}", PTDh.NrBytesToTransfer); 633 this.Log(LogLevel.Noisy, "MaxPacketLength=0{0:X}", PTDh.MaxPacketLength); 634 this.Log(LogLevel.Noisy, "Mult=0{0:X}", PTDh.Mult); 635 this.Log(LogLevel.Noisy, "EndPt=0{0:X}", PTDh.EndPt); 636 this.Log(LogLevel.Noisy, "DeviceAddress=0{0:X}", PTDh.DeviceAddress); 637 this.Log(LogLevel.Noisy, "Token=0{0:X}", PTDh.Token); 638 this.Log(LogLevel.Noisy, "EPType=0{0:X}", PTDh.EPType); 639 this.Log(LogLevel.Noisy, "S=0{0:X}", PTDh.S); 640 this.Log(LogLevel.Noisy, "SE=0{0:X}", PTDh.SE); 641 this.Log(LogLevel.Noisy, "PortNumber=0{0:X}", PTDh.PortNumber); 642 this.Log(LogLevel.Noisy, "HubAddress =0{0:X}", PTDh.HubAddress); 643 this.Log(LogLevel.Noisy, "DataStartAddress=0{0:X}", PTDh.DataStartAddress); 644 this.Log(LogLevel.Noisy, "RL=0{0:X}", PTDh.RL); 645 this.Log(LogLevel.Noisy, "NrBytesTransferred=0{0:X}", PTDh.NrBytesTransferred); 646 this.Log(LogLevel.Noisy, "NakCnt=0{0:X}", PTDh.NakCnt); 647 this.Log(LogLevel.Noisy, "Cerr =0{0:X}", PTDh.Cerr); 648 this.Log(LogLevel.Noisy, "DT=0{0:X}", PTDh.DT); 649 this.Log(LogLevel.Noisy, "SC=0{0:X}", PTDh.SC); 650 this.Log(LogLevel.Noisy, "X=0{0:X}", PTDh.X); 651 this.Log(LogLevel.Noisy, "B=0{0:X}", PTDh.B); 652 this.Log(LogLevel.Noisy, "H =0{0:X}", PTDh.H); 653 this.Log(LogLevel.Noisy, "A=0{0:X}", PTDh.A); 654 this.Log(LogLevel.Noisy, "NextPTDPointer =0{0:X}", PTDh.NextPTDPointer); 655 this.Log(LogLevel.Noisy, "J=0{0:X}", PTDh.J); 656 } 657 } 658 } 659 660 if(((address - 0xc00) / 4) % 8 == 1) 661 { 662 ptd[(address - 0xc00) / 32].DW1 = value; 663 } 664 if(((address - 0xc00) / 4) % 8 == 2) 665 { 666 ptd[(address - 0xc00) / 32].DW2 = value; 667 } 668 if(((address - 0xc00) / 4) % 8 == 3) 669 { 670 ptd[(address - 0xc00) / 32].DW3 = value; 671 } 672 if(((address - 0xc00) / 4) % 8 == 4) 673 { 674 ptd[(address - 0xc00) / 32].DW4 = value; 675 } 676 if(((address - 0xc00) / 4) % 8 == 5) 677 { 678 ptd[(address - 0xc00) / 32].DW5 = value; 679 } 680 if(((address - 0xc00) / 4) % 8 == 6) 681 { 682 ptd[(address - 0xc00) / 32].DW6 = value; 683 } 684 if(((address - 0xc00) / 4) % 8 == 7) 685 { 686 ptd[(address - 0xc00) / 32].DW7 = value; 687 } 688 689 } 690 else if(address >= (uint)0x1000 && address <= (uint)0xffff) 691 { 692 Array.Copy(BitConverter.GetBytes(value), 0, payLoad, ((address)), 4); 693 } 694 else 695 { 696 PTDheader PTDh = new PTDheader(); 697 switch((Offset)address) 698 { 699 case Offset.UsbCommand: 700 usbCmd = value; 701 if((value & 0x2) != 0) 702 { 703 usbCmd &= ~0x2u; 704 this.softReset(); 705 break; 706 } 707 708 if((value & 0x1) != 0) 709 { 710 usbSts &= ~(uint)(1 << 12); 711 for(int i=0; i<portSc.Length; i++) 712 { 713 portSc[i].Enable(); 714 } 715 } 716 717 break; 718 case Offset.CompanionPortRouting1: 719 hscpPortRoute[0] = value; 720 break; 721 case Offset.CompanionPortRouting2: 722 hscpPortRoute[1] = value; 723 break; 724 case Offset.AsyncListAddress: 725 asyncListAddress = value; 726 break; 727 case Offset.FrameListBaseAddress: 728 break; 729 case Offset.INTPTDLastPTD: 730 intLastPTD = value; 731 break; 732 case Offset.UsbInterruptEnable: 733 interruptEnableRegister.OnAsyncAdvanceEnable = ((value & (uint)InterruptMask.InterruptOnAsyncAdvance) != 0) ? true : false; 734 interruptEnableRegister.HostSystemErrorEnable = ((value & (uint)InterruptMask.HostSystemError) != 0) ? true : false; 735 interruptEnableRegister.FrameListRolloverEnable = ((value & (uint)InterruptMask.FrameListRollover) != 0) ? true : false; 736 interruptEnableRegister.PortChangeEnable = ((value & (uint)InterruptMask.PortChange) != 0) ? true : false; 737 interruptEnableRegister.USBErrorEnable = ((value & (uint)InterruptMask.USBError) != 0) ? true : false; 738 interruptEnableRegister.Enable = ((value & (uint)InterruptMask.USBInterrupt) != 0) ? true : false; 739 if(interruptEnableRegister.Enable && interruptEnableRegister.PortChangeEnable) 740 { 741 for(int i=0; i<portSc.Length; i++) 742 { 743 if((portSc[i].getValue() & PortStatusAndControlRegister.ConnectStatusChange) != 0) 744 { 745 IRQ.Set(false); 746 usbSts |= (uint)InterruptMask.USBInterrupt | (uint)InterruptMask.PortChange; //raise flags in status register 747 interr |= 1 << 8; 748 IRQ.Set(true); //raise interrupt 749 break; 750 } 751 } 752 } 753 break; 754 755 case Offset.UsbStatus: 756 if((value & (uint)InterruptMask.FrameListRollover) != 0) 757 { 758 usbSts &= ~(uint)(InterruptMask.FrameListRollover); 759 } 760 if((value & (uint)InterruptMask.HostSystemError) != 0) 761 { 762 usbSts &= ~(uint)(InterruptMask.HostSystemError); 763 } 764 if((value & (uint)InterruptMask.InterruptOnAsyncAdvance) != 0) 765 { 766 usbSts &= ~(uint)(InterruptMask.InterruptOnAsyncAdvance); 767 } 768 if((value & (uint)InterruptMask.PortChange) != 0) 769 { 770 usbSts &= ~(uint)(InterruptMask.PortChange); 771 } 772 if((value & (uint)InterruptMask.USBError) != 0) 773 { 774 usbSts &= ~(uint)(InterruptMask.USBError); 775 } 776 if((value & (uint)InterruptMask.USBInterrupt) != 0) 777 { 778 usbSts &= ~(uint)(InterruptMask.USBInterrupt); 779 IRQ.Set(false); //clear interrupt 780 } 781 break; 782 case Offset.ConfiguredFlag: 783 configFlag = value; 784 break; 785 case (Offset)0x330: 786 atlIRQMaskOR = value; 787 break; 788 case Offset.ATLPTDLastPTD: 789 atlLastPTD = value; 790 break; 791 case (Offset)Offset.INTPTDSkipMap: 792 intSkipMap = value; 793 break; 794 case (Offset)Offset.ATLPTDSkipMap: 795 atlSkipMap = value; 796 lock(thisLock) 797 { 798 for(int p=0; p<32; p++) 799 if((atlSkipMap & (1 << p)) == 0) 800 { 801 if((1 << p) == atlLastPTD) 802 { 803 break; 804 } 805 PTDh.V = (ptd[p].DW0) & 0x1; 806 PTDh.NrBytesToTransfer = (ptd[p].DW0 >> 3) & 0x7fff; 807 PTDh.MaxPacketLength = (ptd[p].DW0 >> 18) & 0x7ff; 808 PTDh.Mult = (ptd[p].DW0 >> 29) & 0x2; 809 PTDh.EndPt = (((ptd[p].DW1) & 0x7) << 1) | (ptd[p].DW0 >> 31); 810 PTDh.DeviceAddress = (byte)((ptd[p].DW1 >> 3) & 0x7f); 811 PTDh.Token = (ptd[p].DW1 >> 10) & 0x3; 812 PTDh.EPType = (ptd[p].DW1 >> 12) & 0x3; 813 PTDh.S = (ptd[p].DW1 >> 14) & 0x1; 814 PTDh.SE = (ptd[p].DW1 >> 16) & 0x3; 815 PTDh.PortNumber = (byte)((ptd[p].DW1 >> 18) & 0x7f); 816 PTDh.HubAddress = (byte)((ptd[p].DW1 >> 25) & 0x7f); 817 PTDh.DataStartAddress = (((ptd[p].DW2 >> 8) & 0xffff) << 3) + 0x400; 818 PTDh.RL = (ptd[p].DW2 >> 25) & 0xf; 819 PTDh.NrBytesTransferred = (ptd[p].DW3) & 0x7fff; 820 PTDh.NakCnt = (ptd[p].DW3 >> 19) & 0xf; 821 PTDh.Cerr = (ptd[p].DW3 >> 23) & 0x3; 822 PTDh.DT = (ptd[p].DW3 >> 25) & 0x1; 823 PTDh.SC = (ptd[p].DW3 >> 27) & 0x1; 824 PTDh.X = (ptd[p].DW3 >> 28) & 0x1; 825 PTDh.B = (ptd[p].DW3 >> 29) & 0x1; 826 PTDh.H = (ptd[p].DW3 >> 30) & 0x1; 827 PTDh.A = (ptd[p].DW3 >> 31) & 0x1; 828 PTDh.NextPTDPointer = (ptd[p].DW4) & 0x1F; 829 PTDh.J = (ptd[p].DW4 >> 5) & 0x1; 830 if(PTDh.V != 0) 831 { 832 /* Process Packet */ 833 ProcessPacket(PTDh); 834 /* Set packet done bits */ 835 if(PTDh.A == 0) 836 { 837 ptd[p].DW3 = (uint)(((ptd[p].DW3 | ((((0 >> 3) & 0x7fff) + PTDh.NrBytesTransferred) & 0x7fff) << 0) & 0x7fffffff)); 838 ptd[p].DW3 = ptd[p].DW3 | (PTDh.B << 29); 839 ptd[p].DW3 = ptd[p].DW3 | (PTDh.H << 30); 840 ptd[p].DW0 = ptd[p].DW0 & 0xfffffffe; 841 // ptd[p].DW3 = (ptd[p].DW3&0xff87ffff) | (PTDh.NakCnt<<19); 842 Done(p); 843 } 844 } 845 } 846 if(atlDoneMap != 0) 847 { 848 if((interruptEnableRegister.OnAsyncAdvanceEnable == true) & (interruptEnableRegister.Enable == true)) 849 { 850 usbSts |= (uint)InterruptMask.USBInterrupt | (uint)InterruptMask.InterruptOnAsyncAdvance; //raise flags in status register 851 interr |= 1 << 8; 852 IRQ.Set(true); //raise interrupt 853 } 854 } 855 } 856 ProcessINT(); 857 break; 858 case (Offset)Offset.Interrupt: 859 IRQ.Set(false); 860 interr = (int)value; 861 break; 862 case (Offset)Offset.Memory: 863 this.Log(LogLevel.Noisy, "Memory Banks: {0:x}", value); 864 memoryReg = value; 865 break; 866 case (Offset)Offset.InterruptEnable: 867 interruptEnableRegister.Enable = true; 868 interruptEnableRegister.OnAsyncAdvanceEnable = true; 869 interruptEnableRegister.PortChangeEnable = true; 870 break; 871 case (Offset)Offset.SWReset: 872 swReset = value; 873 if((swReset & (1 << 0)) > 0) 874 { 875 intDoneMap = 0x00000000; 876 intSkipMap = 0xFFFFFFFF; 877 atlSkipMap = 0xFFFFFFFF; 878 atlDoneMap = 0x00000000; 879 atlIRQMaskOR = 0x0000000; 880 intIRQMaskOR = 0x0000000; 881 swReset = 0x00000000; 882 memoryReg = 0x0000000; 883 softReset(); 884 } 885 if((swReset & (1 << 0)) > 0) 886 { 887 intDoneMap = 0x00000000; 888 intSkipMap = 0xFFFFFFFF; 889 atlSkipMap = 0xFFFFFFFF; 890 atlDoneMap = 0x00000000; 891 atlIRQMaskOR = 0x0000000; 892 intIRQMaskOR = 0x0000000; 893 swReset = 0x00000000; 894 memoryReg = 0x0000000; 895 } 896 break; 897 case (Offset)Offset.Scratch: 898 scratch = value; 899 break; 900 901 default: 902 this.LogUnhandledWrite(address, value); 903 break; 904 } 905 } 906 } 907 908 uint counter = 0; 909 findDevice(byte hubNumber, byte portNumber)910 private IUSBPeripheral findDevice(byte hubNumber, byte portNumber) 911 { 912 if(registeredHubs.Count() > 0) 913 { 914 if(portNumber != 0) 915 { 916 IUSBHub hub; 917 IUSBPeripheral device; 918 919 for(byte x=1; x<=registeredHubs.Count; x++) 920 { 921 hub = registeredHubs[x]; 922 for(byte i=1; i<=(byte)hub.NumberOfPorts; i++) 923 if((device = hub.GetDevice(i)) != null) 924 if(device.GetAddress() == 0) 925 return device; 926 } 927 return null; 928 } 929 else 930 { 931 IUSBPeripheral device = registeredDevices[(byte)(portNumber + (byte)1)]; 932 return device; 933 } 934 } 935 return null; 936 } 937 ProcessPacketInt(PTDheader PTDh)938 public void ProcessPacketInt(PTDheader PTDh) 939 { 940 USBPacket packet; 941 packet.bytesToTransfer = PTDh.NrBytesToTransfer; 942 IUSBPeripheral targetDevice; 943 944 if(PTDh.DeviceAddress != 0) 945 { 946 targetDevice = this.findDevice(PTDh.DeviceAddress); 947 } 948 else 949 { 950 targetDevice = this.findDevice(PTDh.HubAddress, PTDh.PortNumber); 951 targetDevice = activeDevice; 952 } 953 if(targetDevice == null) 954 return; 955 956 if(PTDh.V != 0)//if transfer descriptor active 957 { 958 switch((PIDCode)PTDh.Token) 959 { 960 case PIDCode.In://data transfer from device to host 961 { 962 if(PTDh.NrBytesToTransfer > 0) 963 { 964 byte[] inData = null; 965 966 byte[] buff = new byte[PTDh.NrBytesToTransfer]; 967 968 if(PTDh.EPType == 3) 969 { 970 Array.Copy(payLoad, PTDh.DataStartAddress, buff, 0, PTDh.NrBytesToTransfer); 971 packet.data = buff; 972 packet.ep = (byte)PTDh.EndPt; 973 inData = targetDevice.WriteInterrupt(packet);//targetDevice.WriteInterrupt(packet); 974 } 975 976 if(inData != null) 977 { 978 Array.Copy(inData, 0, payLoad, PTDh.DataStartAddress, inData.Length); 979 PTDh.Transferred((uint)inData.Length); 980 PTDh.Done(); 981 } 982 } 983 else 984 { 985 packet.data = null; 986 packet.ep = (byte)PTDh.EndPt; 987 988 if(PTDh.EPType == 0) 989 { 990 targetDevice.GetDataControl(packet); 991 } 992 else 993 { 994 targetDevice.GetDataBulk(packet); 995 } 996 } 997 if(targetDevice.GetTransferStatus() == 6) 998 { 999 PTDh.Bubble(); 1000 PTDh.Done(); 1001 } 1002 if(targetDevice.GetTransferStatus() == 4) 1003 { 1004 PTDh.Stalled(); 1005 PTDh.Done(); 1006 } 1007 } 1008 break; 1009 1010 default: 1011 this.Log(LogLevel.Warning, "Unkonwn PID"); 1012 break; 1013 } 1014 } 1015 } 1016 1017 public int xport = 0; 1018 public USBSetupPacket setupData ; 1019 1020 protected Object thisLock = new Object(); 1021 ProcessPacket(uint addr)1022 public void ProcessPacket(uint addr) 1023 { 1024 lock(thisLock) 1025 { 1026 PTDheader PTDh = new PTDheader(); 1027 1028 for(int p=0; p<32; p++) 1029 if((atlSkipMap & (1 << p)) == 0) 1030 { 1031 if((1 << p) == atlLastPTD) 1032 { 1033 break; 1034 } 1035 PTDh.V = (ptd[p].DW0) & 0x1; 1036 PTDh.NrBytesToTransfer = (ptd[p].DW0 >> 3) & 0x7fff; 1037 PTDh.MaxPacketLength = (ptd[p].DW0 >> 18) & 0x7ff; 1038 PTDh.Mult = (ptd[p].DW0 >> 29) & 0x2; 1039 PTDh.EndPt = (((ptd[p].DW1) & 0x7) << 1) | (ptd[p].DW0 >> 31); 1040 PTDh.DeviceAddress = (byte)((ptd[p].DW1 >> 3) & 0x7f); 1041 PTDh.Token = (ptd[p].DW1 >> 10) & 0x3; 1042 PTDh.EPType = (ptd[p].DW1 >> 12) & 0x3; 1043 PTDh.S = (ptd[p].DW1 >> 14) & 0x1; 1044 PTDh.SE = (ptd[p].DW1 >> 16) & 0x3; 1045 PTDh.PortNumber = (byte)((ptd[p].DW1 >> 18) & 0x7f); 1046 PTDh.HubAddress = (byte)((ptd[p].DW1 >> 25) & 0x7f); 1047 PTDh.DataStartAddress = (((ptd[p].DW2 >> 8) & 0xffff) << 3) + 0x400; 1048 PTDh.RL = (ptd[p].DW2 >> 25) & 0xf; 1049 PTDh.NrBytesTransferred = (ptd[p].DW3) & 0x7fff; 1050 PTDh.NakCnt = (ptd[p].DW3 >> 19) & 0xf; 1051 PTDh.Cerr = (ptd[p].DW3 >> 23) & 0x3; 1052 PTDh.DT = (ptd[p].DW3 >> 25) & 0x1; 1053 PTDh.SC = (ptd[p].DW3 >> 27) & 0x1; 1054 PTDh.X = (ptd[p].DW3 >> 28) & 0x1; 1055 PTDh.B = (ptd[p].DW3 >> 29) & 0x1; 1056 PTDh.H = (ptd[p].DW3 >> 30) & 0x1; 1057 PTDh.A = (ptd[p].DW3 >> 31) & 0x1; 1058 PTDh.NextPTDPointer = (ptd[p].DW4) & 0x1F; 1059 PTDh.J = (ptd[p].DW4 >> 5) & 0x1; 1060 if(PTDh.V != 0) 1061 { 1062 /* Process Packet */ 1063 ProcessPacket(PTDh); 1064 /* Set packet done bits */ 1065 if(PTDh.A == 0) 1066 { 1067 ptd[p].DW3 = (uint)(((ptd[p].DW3 | ((((0 >> 3) & 0x7fff) + PTDh.NrBytesTransferred) & 0x7fff) << 0) & 0x7fffffff)); 1068 ptd[p].DW3 = ptd[p].DW3 | (PTDh.B << 29); 1069 ptd[p].DW3 = ptd[p].DW3 | (PTDh.H << 30); 1070 ptd[p].DW0 = ptd[p].DW0 & 0xfffffffe; 1071 // ptd[p].DW3 = (ptd[p].DW3&0xff87ffff) | (PTDh.NakCnt<<19); 1072 Done(p); 1073 } 1074 } 1075 } 1076 if(atlDoneMap != 0) 1077 { 1078 if((interruptEnableRegister.OnAsyncAdvanceEnable == true) & (interruptEnableRegister.Enable == true)) 1079 { 1080 usbSts |= (uint)InterruptMask.USBInterrupt | (uint)InterruptMask.InterruptOnAsyncAdvance; //raise flags in status register 1081 interr |= 1 << 8; 1082 IRQ.Set(true); //raise interrupt 1083 } 1084 } 1085 } 1086 } 1087 ProcessINT()1088 public void ProcessINT() 1089 { 1090 1091 PTDheader PTDh = new PTDheader(); 1092 for(int p=0; p<32; p++) 1093 if(((1 << p) ^ (intSkipMap & (1 << p))) != 0) 1094 { 1095 if((1 << p) == intLastPTD) 1096 { 1097 break; 1098 } 1099 PTDh.V = (ptdi[p].DW0) & 0x1; 1100 PTDh.NrBytesToTransfer = (ptdi[p].DW0 >> 3) & 0x7fff; 1101 PTDh.MaxPacketLength = (ptdi[p].DW0 >> 18) & 0x7ff; 1102 PTDh.Mult = (ptdi[p].DW0 >> 29) & 0x2; 1103 PTDh.EndPt = (((ptdi[p].DW1) & 0x7) << 1) | (ptdi[p].DW0 >> 31); 1104 PTDh.DeviceAddress = (byte)((ptdi[p].DW1 >> 3) & 0x7f); 1105 PTDh.Token = (ptdi[p].DW1 >> 10) & 0x3; 1106 PTDh.EPType = (ptdi[p].DW1 >> 12) & 0x3; 1107 PTDh.S = (ptdi[p].DW1 >> 14) & 0x1; 1108 PTDh.SE = (ptdi[p].DW1 >> 16) & 0x3; 1109 PTDh.PortNumber = (byte)((ptdi[p].DW1 >> 18) & 0x7f); 1110 PTDh.HubAddress = (byte)((ptdi[p].DW1 >> 25) & 0x7f); 1111 PTDh.DataStartAddress = (((ptdi[p].DW2 >> 8) & 0xffff) << 3) + 0x400; 1112 PTDh.RL = (ptdi[p].DW2 >> 25) & 0xf; 1113 PTDh.NrBytesTransferred = (ptdi[p].DW3) & 0x7fff; 1114 PTDh.NakCnt = (ptdi[p].DW3 >> 19) & 0xf; 1115 PTDh.Cerr = (ptdi[p].DW3 >> 23) & 0x3; 1116 PTDh.DT = (ptdi[p].DW3 >> 25) & 0x1; 1117 PTDh.SC = (ptdi[p].DW3 >> 27) & 0x1; 1118 PTDh.X = (ptdi[p].DW3 >> 28) & 0x1; 1119 PTDh.B = (ptdi[p].DW3 >> 29) & 0x1; 1120 PTDh.H = (ptdi[p].DW3 >> 30) & 0x1; 1121 PTDh.A = (ptdi[p].DW3 >> 31) & 0x1; 1122 PTDh.NextPTDPointer = (ptdi[p].DW4) & 0x1F; 1123 PTDh.J = (ptdi[p].DW4 >> 5) & 0x1; 1124 //if(addr == PTDh.DeviceAddress) 1125 { 1126 1127 if(PTDh.V != 0) 1128 { 1129 /* Process Packet */ 1130 ProcessPacketInt(PTDh); 1131 if(PTDh.V == 0) 1132 { 1133 /* Set packet done bits */ 1134 1135 ptdi[p].DW0 = ptdi[p].DW0 & 0xfffffffe; 1136 ptdi[p].DW3 = (uint)(((ptdi[p].DW3 | ((((0 >> 3) & 0x7fff) + PTDh.NrBytesTransferred) & 0x7fff) << 0) & 0x7fffffff)); 1137 ptdi[p].DW3 = ptdi[p].DW3 | (PTDh.B << 29); 1138 ptdi[p].DW3 = ptdi[p].DW3 | (PTDh.H << 30); 1139 ptdi[p].DW4 = ptdi[p].DW4 & 0xfffffffe; 1140 DoneInt(p); 1141 if((interruptEnableRegister.OnAsyncAdvanceEnable == true) & (interruptEnableRegister.Enable == true)) 1142 { 1143 usbSts |= (uint)InterruptMask.USBInterrupt | (uint)InterruptMask.InterruptOnAsyncAdvance; //raise flags in status register 1144 interr |= 1 << 7; 1145 IRQ.Set(true); //raise interrupt 1146 } 1147 } 1148 } 1149 } 1150 } 1151 } 1152 1153 ProcessINT(uint addr)1154 public void ProcessINT(uint addr) 1155 { 1156 1157 PTDheader PTDh = new PTDheader(); 1158 for(int p=0; p<32; p++) 1159 if(((1 << p) ^ (intSkipMap & (1 << p))) != 0) 1160 { 1161 if((1 << p) == intLastPTD) 1162 { 1163 break; 1164 } 1165 PTDh.V = (ptdi[p].DW0) & 0x1; 1166 PTDh.NrBytesToTransfer = (ptdi[p].DW0 >> 3) & 0x7fff; 1167 PTDh.MaxPacketLength = (ptdi[p].DW0 >> 18) & 0x7ff; 1168 PTDh.Mult = (ptdi[p].DW0 >> 29) & 0x2; 1169 PTDh.EndPt = (((ptdi[p].DW1) & 0x7) << 1) | (ptdi[p].DW0 >> 31); 1170 PTDh.DeviceAddress = (byte)((ptdi[p].DW1 >> 3) & 0x7f); 1171 PTDh.Token = (ptdi[p].DW1 >> 10) & 0x3; 1172 PTDh.EPType = (ptdi[p].DW1 >> 12) & 0x3; 1173 PTDh.S = (ptdi[p].DW1 >> 14) & 0x1; 1174 PTDh.SE = (ptdi[p].DW1 >> 16) & 0x3; 1175 PTDh.PortNumber = (byte)((ptdi[p].DW1 >> 18) & 0x7f); 1176 PTDh.HubAddress = (byte)((ptdi[p].DW1 >> 25) & 0x7f); 1177 PTDh.DataStartAddress = (((ptdi[p].DW2 >> 8) & 0xffff) << 3) + 0x400; 1178 PTDh.RL = (ptdi[p].DW2 >> 25) & 0xf; 1179 PTDh.NrBytesTransferred = (ptdi[p].DW3) & 0x7fff; 1180 PTDh.NakCnt = (ptdi[p].DW3 >> 19) & 0xf; 1181 PTDh.Cerr = (ptdi[p].DW3 >> 23) & 0x3; 1182 PTDh.DT = (ptdi[p].DW3 >> 25) & 0x1; 1183 PTDh.SC = (ptdi[p].DW3 >> 27) & 0x1; 1184 PTDh.X = (ptdi[p].DW3 >> 28) & 0x1; 1185 PTDh.B = (ptdi[p].DW3 >> 29) & 0x1; 1186 PTDh.H = (ptdi[p].DW3 >> 30) & 0x1; 1187 PTDh.A = (ptdi[p].DW3 >> 31) & 0x1; 1188 PTDh.NextPTDPointer = (ptdi[p].DW4) & 0x1F; 1189 PTDh.J = (ptdi[p].DW4 >> 5) & 0x1; 1190 if(addr == PTDh.DeviceAddress) 1191 { 1192 1193 if(PTDh.V != 0) 1194 { 1195 /* Process Packet */ 1196 ProcessPacketInt(PTDh); 1197 if(PTDh.V == 0) 1198 { 1199 /* Set packet done bits */ 1200 1201 ptdi[p].DW0 = ptdi[p].DW0 & 0xfffffffe; 1202 ptdi[p].DW3 = (uint)(((ptdi[p].DW3 | ((((0 >> 3) & 0x7fff) + PTDh.NrBytesTransferred) & 0x7fff) << 0) & 0x7fffffff)); 1203 ptdi[p].DW3 = ptdi[p].DW3 | (PTDh.B << 29); 1204 ptdi[p].DW3 = ptdi[p].DW3 | (PTDh.H << 30); 1205 ptdi[p].DW4 = ptdi[p].DW4 & 0xfffffffe; 1206 DoneInt(p); 1207 if((interruptEnableRegister.OnAsyncAdvanceEnable == true) & (interruptEnableRegister.Enable == true)) 1208 { 1209 usbSts |= (uint)InterruptMask.USBInterrupt | (uint)InterruptMask.InterruptOnAsyncAdvance; //raise flags in status register 1210 interr |= 1 << 7; 1211 IRQ.Set(true); //raise interrupt 1212 } 1213 } 1214 } 1215 } 1216 } 1217 } 1218 ProcessPacket(PTDheader PTDh)1219 public void ProcessPacket(PTDheader PTDh) 1220 { 1221 1222 IUSBPeripheral targetDevice; 1223 if(PTDh.DeviceAddress != 0) 1224 { 1225 targetDevice = this.findDevice(PTDh.DeviceAddress); 1226 } 1227 else 1228 { 1229 targetDevice = this.findDevice(PTDh.HubAddress, PTDh.PortNumber); 1230 targetDevice = activeDevice; 1231 } 1232 if(targetDevice == null) 1233 { 1234 return; 1235 } 1236 if(PTDh.V != 0)//if transfer descriptor active 1237 { 1238 USBPacket packet; 1239 packet.bytesToTransfer = PTDh.NrBytesToTransfer; 1240 switch((PIDCode)PTDh.Token) 1241 { 1242 case PIDCode.Setup://if setup command 1243 this.Log(LogLevel.Noisy, "Setup"); 1244 this.Log(LogLevel.Noisy, "Device {0:d}", PTDh.DeviceAddress); 1245 1246 setupData.requestType = payLoad[PTDh.DataStartAddress]; 1247 setupData.request = payLoad[PTDh.DataStartAddress + 1]; 1248 setupData.value = BitConverter.ToUInt16(payLoad, (int)(PTDh.DataStartAddress + 2)); 1249 setupData.index = BitConverter.ToUInt16(payLoad, (int)(PTDh.DataStartAddress + 4)); 1250 setupData.length = BitConverter.ToUInt16(payLoad, (int)(PTDh.DataStartAddress + 6)); 1251 packet.ep = (byte)PTDh.EndPt; 1252 packet.data = null; 1253 1254 if(((setupData.requestType & 0x80u) >> 7) == (uint)DataDirection.DeviceToHost)//if device to host transfer 1255 { 1256 if(((setupData.requestType & 0x60u) >> 5) == (uint)USBRequestType.Standard) 1257 { 1258 if(PTDh.DeviceAddress == 3) 1259 { 1260 this.Log(LogLevel.Warning, "Setup"); 1261 } 1262 1263 switch((DeviceRequestType)setupData.request) 1264 { 1265 case DeviceRequestType.GetDescriptor: 1266 targetDevice.GetDescriptor(packet, setupData); 1267 break; 1268 case DeviceRequestType.GetConfiguration: 1269 targetDevice.GetConfiguration(); 1270 break; 1271 case DeviceRequestType.GetInterface: 1272 targetDevice.GetInterface(packet, setupData); 1273 break; 1274 case DeviceRequestType.GetStatus: 1275 targetDevice.GetStatus(packet, setupData); 1276 break; 1277 default: 1278 targetDevice.GetDescriptor(packet, setupData); 1279 this.Log(LogLevel.Warning, "Unsupported device request1"); 1280 break; 1281 1282 }//end of switch request 1283 } 1284 else if(((setupData.requestType & 0x60u) >> 5) == (uint)USBRequestType.Class) 1285 { 1286 targetDevice.ProcessClassGet(packet, setupData); 1287 1288 } 1289 else if(((setupData.requestType & 0x60u) >> 5) == (uint)USBRequestType.Vendor) 1290 { 1291 targetDevice.ProcessVendorGet(packet, setupData); 1292 1293 } 1294 } 1295 else//if host to device transfer 1296 if(((setupData.requestType & 0x60) >> 5) == (uint)USBRequestType.Standard) 1297 { 1298 switch((DeviceRequestType)setupData.request) 1299 { 1300 case DeviceRequestType.SetAddress: 1301 targetDevice.SetAddress(setupData.value); 1302 targetDevice.SendInterrupt += ProcessINT; 1303 targetDevice.SendPacket += ProcessPacket; 1304 this.addressDevice(targetDevice, (byte)setupData.value); 1305 counter++; 1306 break; 1307 case DeviceRequestType.SetDescriptor: 1308 targetDevice.GetDescriptor(packet, setupData); 1309 1310 break; 1311 case DeviceRequestType.SetFeature: 1312 targetDevice.GetDescriptor(packet, setupData); 1313 1314 break; 1315 case DeviceRequestType.SetInterFace: 1316 targetDevice.SetInterface(packet, setupData); 1317 1318 break; 1319 case DeviceRequestType.SetConfiguration: 1320 1321 targetDevice.SetConfiguration(packet, setupData); 1322 1323 break; 1324 1325 default: 1326 this.Log(LogLevel.Warning, "Unsupported device request2"); 1327 break; 1328 1329 }//end of switch request 1330 }//end of request type.standard 1331 else 1332 1333 if((setupData.requestType >> 5) == (uint)USBRequestType.Class) 1334 { 1335 targetDevice.ProcessClassSet(packet, setupData); 1336 } 1337 else if((setupData.requestType >> 5) == (uint)USBRequestType.Vendor) 1338 { 1339 targetDevice.ProcessVendorSet(packet, setupData); 1340 1341 } 1342 1343 PTDh.Transferred((uint)PTDh.NrBytesToTransfer); 1344 PTDh.Done(); 1345 1346 1347 break; 1348 1349 case PIDCode.Out://data transfer from host to device 1350 { 1351 uint dataAmount; 1352 1353 dataAmount = PTDh.NrBytesToTransfer; 1354 1355 if(dataAmount > 0) 1356 { 1357 byte[] tdData = new byte[dataAmount]; 1358 Array.Copy(payLoad, PTDh.DataStartAddress, tdData, 0, dataAmount); 1359 1360 if(PTDh.EPType == 0) 1361 { 1362 packet.ep = (byte)PTDh.EndPt; 1363 packet.data = tdData; 1364 targetDevice.GetDescriptor(packet, setupData); 1365 } 1366 else 1367 { 1368 packet.data = tdData; 1369 packet.ep = (byte)PTDh.EndPt; 1370 targetDevice.WriteDataBulk(packet); 1371 } 1372 } 1373 else 1374 { 1375 packet.data = null; 1376 packet.ep = (byte)PTDh.EndPt; 1377 1378 targetDevice.WriteDataBulk(packet); 1379 } 1380 1381 PTDh.Transferred(dataAmount); 1382 PTDh.Done(); 1383 1384 } 1385 break; 1386 case PIDCode.In://data transfer from device to host 1387 { 1388 if(PTDh.NrBytesToTransfer > 0) 1389 { 1390 byte[] inData = null; 1391 1392 byte[] buff = new byte[PTDh.NrBytesToTransfer]; 1393 1394 if(PTDh.EPType == 0) 1395 { 1396 packet.data = buff; 1397 packet.ep = (byte)PTDh.EndPt; 1398 inData = targetDevice.GetDataControl(packet); 1399 } 1400 else 1401 { 1402 packet.data = buff; 1403 packet.ep = (byte)PTDh.EndPt; 1404 inData = targetDevice.GetDataBulk(packet); 1405 if(inData == null) 1406 return; 1407 } 1408 1409 if(inData != null) 1410 { 1411 1412 if(PTDh.NrBytesToTransfer > 0) 1413 { 1414 Array.Copy(inData, 0, payLoad, PTDh.DataStartAddress, inData.Length); 1415 PTDh.Transferred((uint)inData.Length); 1416 } 1417 } 1418 } 1419 else 1420 { 1421 if(PTDh.EPType == 0) 1422 { 1423 packet.data = null; 1424 packet.ep = (byte)PTDh.EndPt; 1425 targetDevice.GetDataControl(packet); 1426 } 1427 else 1428 { 1429 packet.data = null; 1430 packet.ep = (byte)PTDh.EndPt; 1431 targetDevice.GetDataBulk(packet); 1432 } 1433 } 1434 1435 1436 PTDh.Done(); 1437 } 1438 break; 1439 1440 default: 1441 this.Log(LogLevel.Warning, "Unkonwn PID"); 1442 break; 1443 } 1444 } 1445 else 1446 { 1447 this.Log(LogLevel.Info, "Inactive transfed descriptor not processing at this point"); 1448 } 1449 } 1450 public class PTD 1451 { 1452 public uint DW0 1453 { 1454 get; 1455 set; 1456 } 1457 1458 public uint DW1 1459 { 1460 get; 1461 set; 1462 } 1463 1464 public uint DW2 1465 { 1466 get; 1467 set; 1468 } 1469 1470 public uint DW3 1471 { 1472 get; 1473 set; 1474 } 1475 1476 public uint DW4 1477 { 1478 get; 1479 set; 1480 } 1481 1482 public uint DW5 1483 { 1484 get; 1485 set; 1486 } 1487 1488 public uint DW6 1489 { 1490 get; 1491 set; 1492 } 1493 1494 public uint DW7 1495 { 1496 get; 1497 set; 1498 } 1499 }; 1500 #region EHCI operational register set 1501 public PortStatusAndControlRegister[] portSc; //port status control 1502 public uint usbCmd = 0x00080000; //usb command 1503 public uint usbSts = 0x0000000; //usb status 1504 public uint usbFrIndex = 0; //usb frame index 1505 public uint asyncListAddress; //next async addres 1506 public uint configFlag; // configured flag registers 1507 public InterruptEnable interruptEnableRegister = new InterruptEnable(); 1508 #endregion 1509 1510 #region EHCI Host controller capability register 1511 private uint[] hscpPortRoute = new uint [2]; 1512 private const uint capBase = (hciVersion & 0xffff) << 16 | ((opBase) & 0xff) << 0;//lenght + version (0x00) (RO) 1513 private uint hCSParams = 0; //structural parameters (addr 0x04) (RO) 1514 private uint hCCParams = 0; //capability parameters (addr 0x08) (RO) 1515 #endregion 1516 1517 #region EHCI controller configuration 1518 private const uint hciVersion = 0x0100;//hci version (16 bit BCD) 1519 public const uint opBase = 0x20; //operational registers base addr 1520 private const uint nCC = 0; //number of companion controllers 1521 private const uint nPCC = 0; //number of ports per companion controller 1522 #endregion 1523 public bool outBool = false; 1524 1525 private enum Offset : uint 1526 { 1527 /* capability registers ... */ 1528 CapabilityLength = 0x00, 1529 StructuralParameters = 0x04, 1530 CapabilityParameters = 0x08, 1531 CompanionPortRouting1 = 0x0C, 1532 CompanionPortRouting2 = 0x10, 1533 1534 /* operational registers ... */ 1535 UsbCommand = opBase, 1536 UsbStatus = opBase + 0x04, 1537 UsbInterruptEnable = opBase + 0x08, 1538 UsbFrameIndex = opBase + 0x0C, 1539 ControlSegment = opBase + 0x10, 1540 FrameListBaseAddress = opBase + 0x14, 1541 AsyncListAddress = opBase + 0x18, 1542 ConfiguredFlag = opBase + 0x40, 1543 PortStatusControl = opBase + 0x44, 1544 1545 /* Additional EHCI operational registers */ 1546 ISOPTDDoneMap = 0x0130, 1547 ISOPTDSkipMap = 0x0134, 1548 ISOPTDLastPTD = 0x0138, 1549 INTPTDDoneMap = 0x0140, 1550 INTPTDSkipMap = 0x0144, 1551 INTPTDLastPTD = 0x0148, 1552 ATLPTDDoneMap = 0x0150, 1553 ATLPTDSkipMap = 0x0154, 1554 ATLPTDLastPTD = 0x0158, 1555 1556 /* Configuration registers */ 1557 HWModeControl = 0x0300, 1558 ChipID = 0x0304, 1559 Scratch = 0x0308, 1560 SWReset = 0x030C, 1561 DMAConfiguration = 0x0330, 1562 BufferStatus = 0x0334, 1563 ATLDoneTimeout = 0x0338, 1564 Memory = 0x033C, 1565 EdgeInterruptCount = 0x0340, 1566 DMAStartAddress = 0x0344, 1567 PowerDownControl = 0x0354, 1568 Port1Control = 0x0374, 1569 1570 /* Interrupt registers */ 1571 Interrupt = 0x0310, 1572 InterruptEnable = 0x0314, 1573 ISOIRQMaskOR = 0x0318, 1574 INTIRQMaskOR = 0x031C, 1575 ATLIRQMaskOR = 0x0320, 1576 ISOIRQMaskAND = 0x0324, 1577 INTIRQMaskAND = 0x0328, 1578 ATLIRQMaskAND = 0x032C 1579 } 1580 1581 protected enum PIDCode 1582 { 1583 Out = 0, 1584 In = 1, 1585 Setup = 2 1586 } 1587 1588 private enum DataDirection 1589 { 1590 HostToDevice = 0, 1591 DeviceToHost = 1 1592 } 1593 1594 private enum DeviceRequestType 1595 { 1596 GetStatus = 0, 1597 ClearFeature = 1, 1598 SetFeature = 3, 1599 SetAddress = 5, 1600 GetDescriptor = 6, 1601 SetDescriptor = 7, 1602 GetConfiguration = 8, 1603 SetConfiguration = 9, 1604 GetInterface = 10, 1605 SetInterFace = 11, 1606 SynchFrame = 12 1607 } 1608 1609 public class InterruptEnable 1610 { 1611 public bool OnAsyncAdvanceEnable = false; 1612 public bool HostSystemErrorEnable = false; 1613 public bool FrameListRolloverEnable = false; 1614 public bool PortChangeEnable = false; 1615 public bool USBErrorEnable = false; 1616 public bool Enable = false; 1617 getRegister()1618 public uint getRegister() 1619 { 1620 uint regValue = 0; 1621 regValue |= (uint)(OnAsyncAdvanceEnable ? 1 : 0) << 5; 1622 regValue |= (uint)(HostSystemErrorEnable ? 1 : 0) << 4; 1623 regValue |= (uint)(FrameListRolloverEnable ? 1 : 0) << 3; 1624 regValue |= (uint)(PortChangeEnable ? 1 : 0) << 2; 1625 regValue |= (uint)(USBErrorEnable ? 1 : 0) << 1; 1626 regValue |= (uint)(Enable ? 1 : 0) << 0; 1627 return regValue; 1628 } 1629 } 1630 1631 public enum InterruptMask:uint //same mask for Int Enable ane USB Status registers 1632 { 1633 InterruptOnAsyncAdvance = (uint)(1 << 5), 1634 HostSystemError = (uint)(1 << 4), 1635 FrameListRollover = (uint)(1 << 3), 1636 PortChange = (uint)(1 << 2), 1637 USBError = (uint)(1 << 1), 1638 USBInterrupt = (uint)(1 << 0) 1639 } AttachHUBDevice(IUSBPeripheral device, byte port)1640 public void AttachHUBDevice(IUSBPeripheral device, byte port) 1641 { 1642 registeredDevices.Add(port, device); 1643 1644 PortStatusAndControlRegisterChanges change = portSc[port - 1].Attach(); 1645 1646 if(change.ConnectChange == true) 1647 { 1648 usbSts |= (uint)InterruptMask.PortChange; 1649 } 1650 1651 if((interruptEnableRegister.Enable == true) && (interruptEnableRegister.PortChangeEnable == true)) 1652 { 1653 usbSts |= (uint)InterruptMask.USBInterrupt | (uint)InterruptMask.PortChange; //raise flags in status register 1654 interr |= 1 << 7; 1655 IRQ.Set(true); //raise interrupt 1656 } 1657 } 1658 DetachDevice(byte port)1659 public void DetachDevice(byte port) 1660 { 1661 registeredDevices.Remove(port); 1662 } 1663 DetachHUBDevice(uint addr, uint port)1664 public void DetachHUBDevice(uint addr, uint port) 1665 { 1666 PTDheader PTDh = new PTDheader(); 1667 for(int p=0; p<32; p++) 1668 1669 if(((1 << p) ^ (intSkipMap & (1 << p))) != 0) 1670 { 1671 if((1 << p) == intLastPTD) 1672 { 1673 break; 1674 } 1675 PTDh.V = (ptdi[p].DW0) & 0x1; 1676 PTDh.NrBytesToTransfer = (ptdi[p].DW0 >> 3) & 0x7fff; 1677 PTDh.MaxPacketLength = (ptdi[p].DW0 >> 18) & 0x7ff; 1678 PTDh.Mult = (ptdi[p].DW0 >> 29) & 0x2; 1679 PTDh.EndPt = (((ptdi[p].DW1) & 0x7) << 1) | (ptdi[p].DW0 >> 31); 1680 PTDh.DeviceAddress = (byte)((ptdi[p].DW1 >> 3) & 0x7f); 1681 PTDh.Token = (ptdi[p].DW1 >> 10) & 0x3; 1682 PTDh.EPType = (ptdi[p].DW1 >> 12) & 0x3; 1683 PTDh.S = (ptdi[p].DW1 >> 14) & 0x1; 1684 PTDh.SE = (ptdi[p].DW1 >> 16) & 0x3; 1685 PTDh.PortNumber = (byte)((ptdi[p].DW1 >> 18) & 0x7f); 1686 PTDh.HubAddress = (byte)((ptdi[p].DW1 >> 25) & 0x7f); 1687 PTDh.DataStartAddress = (((ptdi[p].DW2 >> 8) & 0xffff) << 3) + 0x400; 1688 PTDh.RL = (ptdi[p].DW2 >> 25) & 0xf; 1689 PTDh.NrBytesTransferred = (ptdi[p].DW3) & 0x7fff; 1690 PTDh.NakCnt = (ptdi[p].DW3 >> 19) & 0xf; 1691 PTDh.Cerr = (ptdi[p].DW3 >> 23) & 0x3; 1692 PTDh.DT = (ptdi[p].DW3 >> 25) & 0x1; 1693 PTDh.SC = (ptdi[p].DW3 >> 27) & 0x1; 1694 PTDh.X = (ptdi[p].DW3 >> 28) & 0x1; 1695 PTDh.B = (ptdi[p].DW3 >> 29) & 0x1; 1696 PTDh.H = (ptdi[p].DW3 >> 30) & 0x1; 1697 PTDh.A = (ptdi[p].DW3 >> 31) & 0x1; 1698 PTDh.NextPTDPointer = (ptdi[p].DW4) & 0x1F; 1699 PTDh.J = (ptdi[p].DW4 >> 5) & 0x1; 1700 if(addr == PTDh.DeviceAddress) 1701 { 1702 if(PTDh.V != 0) 1703 { 1704 /* Process Packet */ 1705 ProcessPacketInt(PTDh); 1706 /* Set packet done bits */ 1707 { 1708 ptdi[p].DW0 = ptdi[p].DW0 & 0xfffffffe; 1709 ptdi[p].DW3 = (uint)(((ptdi[p].DW3 | ((((0 >> 3) & 0x7fff) + PTDh.NrBytesTransferred) & 0x7fff) << 0) & 0x7fffffff)); 1710 ptdi[p].DW3 = ptdi[p].DW3 | (PTDh.B << 29); 1711 ptdi[p].DW3 = ptdi[p].DW3 | (PTDh.H << 30); 1712 ptdi[p].DW4 = ptdi[p].DW4 & 0xfffffffe; 1713 DoneInt(p); 1714 1715 if((interruptEnableRegister.OnAsyncAdvanceEnable == true) & (interruptEnableRegister.Enable == true)) 1716 { 1717 usbSts |= (uint)InterruptMask.USBInterrupt | (uint)InterruptMask.InterruptOnAsyncAdvance; //raise flags in status register 1718 interr |= 1 << 7; 1719 IRQ.Set(true); //raise interrupt 1720 } 1721 } 1722 } 1723 1724 IUSBHub hub; 1725 IUSBPeripheral device; 1726 1727 for(byte x=1; x<=registeredHubs.Count; x++) 1728 { 1729 hub = registeredHubs[x]; 1730 if(hub.GetAddress() == port) 1731 { 1732 for(byte i=1; i<=(byte)hub.NumberOfPorts; i++) 1733 if((device = hub.GetDevice(i)) != null) 1734 if(device.GetAddress() != 0) 1735 1736 RemoveFromHub(device); 1737 1738 registeredHubs.Remove((byte)x); 1739 } 1740 } 1741 adressedDevices.Remove((byte)port); 1742 } 1743 } 1744 1745 } 1746 RemoveFromHub(IUSBPeripheral dev)1747 public void RemoveFromHub(IUSBPeripheral dev) 1748 { 1749 IUSBHub hub; 1750 IUSBPeripheral device; 1751 for(byte x=1; x<=registeredHubs.Count; x++) 1752 { 1753 hub = registeredHubs[x]; 1754 if(hub.GetAddress() == dev.GetAddress()) 1755 { 1756 for(byte i=1; i<=(byte)hub.NumberOfPorts; i++) 1757 if((device = hub.GetDevice(i)) != null) 1758 if(device.GetAddress() != 0) 1759 RemoveFromHub(device); 1760 else 1761 adressedDevices.Remove((byte)device.GetAddress()); 1762 registeredHubs.Remove((byte)x); 1763 } 1764 } 1765 adressedDevices.Remove((byte)dev.GetAddress()); 1766 } 1767 1768 public Dictionary<byte,IUSBPeripheral> DeviceList 1769 { 1770 get; 1771 set; 1772 } 1773 FindDevice(byte port)1774 public IUSBPeripheral FindDevice(byte port) 1775 { 1776 throw new NotImplementedException(); 1777 } 1778 1779 public IUSBHub Parent 1780 { 1781 get; 1782 set; 1783 } 1784 public class PTDheader 1785 { 1786 public PTDheader()1787 PTDheader() 1788 { 1789 V = 0; 1790 NrBytesToTransfer = 0; 1791 MaxPacketLength = 0; 1792 Mult = 0; 1793 EndPt = 0; 1794 DeviceAddress = 0; 1795 Token = 0; 1796 EPType = 0; 1797 S = 0; 1798 SE = 0; 1799 PortNumber = 0; 1800 HubAddress = 0; 1801 DataStartAddress = 0; 1802 RL = 0; 1803 NrBytesTransferred = 0; 1804 NakCnt = 0; 1805 Cerr = 0; 1806 DT = 0; 1807 SC = 0; 1808 X = 0; 1809 B = 0; 1810 H = 0; 1811 A = 0; 1812 NextPTDPointer = 0; 1813 J = 0; 1814 } 1815 Transferred(uint amount)1816 public void Transferred(uint amount) 1817 { 1818 NrBytesTransferred += amount; 1819 } 1820 Bubble()1821 public void Bubble() 1822 { 1823 B = 1; 1824 V = 0; 1825 A = 0; 1826 } 1827 Stalled()1828 public void Stalled() 1829 { 1830 H = 1; 1831 V = 0; 1832 A = 0; 1833 } 1834 Done()1835 public void Done() 1836 { 1837 V = 0; 1838 A = 0; 1839 } 1840 Nak()1841 public void Nak() 1842 { 1843 V = 0; 1844 A = 0; 1845 NakCnt = 0; 1846 } 1847 1848 public uint V ; 1849 public uint NrBytesToTransfer ; 1850 public uint MaxPacketLength ; 1851 public uint Mult ; 1852 public uint EndPt ; 1853 public byte DeviceAddress; 1854 public uint Token ; 1855 public uint EPType ; 1856 public uint S ; 1857 public uint SE; 1858 public byte PortNumber ; 1859 public byte HubAddress ; 1860 public uint DataStartAddress ; 1861 public uint RL ; 1862 public uint NrBytesTransferred ; 1863 public uint NakCnt ; 1864 public uint Cerr ; 1865 public uint DT ; 1866 public uint SC ; 1867 public uint X ; 1868 public uint B ; 1869 public uint H ; 1870 public uint A ; 1871 public uint NextPTDPointer ; 1872 public uint J ; 1873 } 1874 private PTD[] ptd = new PTD[32]; 1875 private PTD[] ptdi = new PTD[32]; 1876 private uint intDoneMap; 1877 private uint intSkipMap; 1878 private uint intLastPTD; 1879 private uint atlSkipMap; 1880 private PCIInfo pci_info; 1881 private uint atlLastPTD; 1882 private uint atlDoneMap; 1883 private uint atlIRQMaskOR; 1884 private uint scratch = 0xdeadbabe; 1885 private uint intIRQMaskOR; 1886 private uint swReset; 1887 private uint memoryReg; 1888 private int interr; 1889 private byte[] payLoad = new byte[0x10000]; 1890 } 1891 } 1892