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