Exemplo n.º 1
0
        protected UHCI_qTD_Struct *CreateQTD_IO(UHCI_QueueHead_Struct *uQH, uint *next, byte direction, bool toggle, ushort tokenBytes, byte device, byte endpoint, uint packetSize)
        {
#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: Create qTD IO");
            BasicConsole.DelayOutput(5);
#endif

            UHCI_qTD_Struct *td = AllocQTD(next);

            UHCI_qTD.SetPacketID(td, direction);

            if (tokenBytes != 0)
            {
                UHCI_qTD.SetMaxLength(td, (ushort)((tokenBytes - 1u) & 0x7FFu));
            }
            else
            {
                UHCI_qTD.SetMaxLength(td, 0x7FF);
            }

            UHCI_qTD.SetDataToggle(td, toggle);
            UHCI_qTD.SetC_ERR(td, 0x3);
            UHCI_qTD.SetDeviceAddress(td, device);
            UHCI_qTD.SetEndpoint(td, endpoint);

            AllocQTDbuffer(td);

            uQH->q_last = td;
            return(td);
        }
Exemplo n.º 2
0
        protected UHCI_qTD_Struct *CreateQTD_SETUP(UHCI_QueueHead_Struct *uQH, uint *next, bool toggle, ushort tokenBytes, byte type, byte req, byte hiVal, byte loVal, ushort i, ushort length, byte device, byte endpoint, uint packetSize)
        {
#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: Create qTD SETUP");
            BasicConsole.DelayOutput(5);
#endif

            UHCI_qTD_Struct *td = AllocQTD(next);

            UHCI_qTD.SetPacketID(td, UHCI_Consts.TD_SETUP);
            UHCI_qTD.SetDataToggle(td, toggle);
            UHCI_qTD.SetDeviceAddress(td, device);
            UHCI_qTD.SetEndpoint(td, endpoint);
            UHCI_qTD.SetMaxLength(td, (ushort)(tokenBytes - 1));
            UHCI_qTD.SetC_ERR(td, 0x3);

            //TODO: *buffer =
            USBRequest *request = (USBRequest *)(AllocQTDbuffer(td));
            request->type    = type;
            request->request = req;
            request->valueHi = hiVal;
            request->valueLo = loVal;
            request->index   = i;
            request->length  = length;

            uQH->q_last = td;
            return(td);
        }
Exemplo n.º 3
0
        protected void CreateQH(UHCI_QueueHead_Struct *head, uint horizPtr, UHCI_qTD_Struct *firstTD)
        {
#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: Create QH");
            BasicConsole.DelayOutput(5);
#endif

            head->next = (UHCI_QueueHead_Struct *)UHCI_Consts.BIT_T; // (paging_getPhysAddr((void*)horizPtr) & 0xFFFFFFF0) | BIT_QH;

            if (firstTD == null)
            {
                head->transfer = (UHCI_qTD_Struct *)UHCI_Consts.BIT_T;
            }
            else
            {
                head->transfer = (UHCI_qTD_Struct *)((uint)VirtMemManager.GetPhysicalAddress(firstTD) & 0xFFFFFFF0);
                head->q_first  = firstTD;
            }
        }
Exemplo n.º 4
0
        protected void ResetHC()
        {
#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: ResetHC");
            BasicConsole.DelayOutput(5);
#endif

            //Processes.Scheduler.Disable();

            // http://www.lowlevel.eu/wiki/Universal_Host_Controller_Interface#Informationen_vom_PCI-Treiber_holen

            ushort legacySupport = pciDevice.ReadRegister16(UHCI_Consts.PCI_LEGACY_SUPPORT);
            pciDevice.WriteRegister16(UHCI_Consts.PCI_LEGACY_SUPPORT, UHCI_Consts.PCI_LEGACY_SUPPORT_STATUS); // resets support status bits in Legacy support register
                
            USBCMD.Write_UInt16(UHCI_Consts.CMD_GRESET);
            Hardware.Devices.Timer.Default.Wait(50);
            USBCMD.Write_UInt16(0);
            
            RootPortCount = (byte)(pciDevice.BaseAddresses[4].Size() / 2);
#if UHCI_TRACE
            BasicConsole.WriteLine(((FOS_System.String)"UHCI: RootPortCount=") + RootPortCount);
#endif
            for (byte i = 2; i < RootPortCount; i++)
            {
                if ((PORTSC1.Read_UInt16((ushort)(i * 2)) & UHCI_Consts.PORT_VALID) == 0 ||
                   (PORTSC1.Read_UInt16((ushort)(i * 2)) == 0xFFFF))
                {
                    RootPortCount = i;
                    break;
                }
            }
#if UHCI_TRACE
            BasicConsole.WriteLine(((FOS_System.String)"UHCI: RootPortCount=") + RootPortCount);
#endif

            if (RootPortCount > UHCI_Consts.PORTMAX)
            {
                RootPortCount = UHCI_Consts.PORTMAX;
            }
#if UHCI_TRACE
            BasicConsole.WriteLine(((FOS_System.String)"UHCI: RootPortCount=") + RootPortCount);
            BasicConsole.DelayOutput(1);
#endif

            RootPorts.Empty();
            for (byte i = 0; i < RootPortCount; i++)
            {
                RootPorts.Add(new HCPort()
                {
                    portNum = i
                });
            }
            
#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: Checking HC state: Get USBCMD...");
            BasicConsole.DelayOutput(1);
#endif

            ushort usbcmd = USBCMD.Read_UInt16();
#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: Checking HC state: Check...");
            BasicConsole.DelayOutput(1);
#endif
            if ((legacySupport & ~(UHCI_Consts.PCI_LEGACY_SUPPORT_STATUS | UHCI_Consts.PCI_LEGACY_SUPPORT_NO_CHG | UHCI_Consts.PCI_LEGACY_SUPPORT_PIRQ)) != 0 ||
                (usbcmd & UHCI_Consts.CMD_RS) != 0 ||
                (usbcmd & UHCI_Consts.CMD_CF) != 0 ||
                (usbcmd & UHCI_Consts.CMD_EGSM) == 0 ||
                (USBINTR.Read_UInt16() & UHCI_Consts.INT_MASK) != 0)
            {
#if UHCI_TRACE
                BasicConsole.WriteLine("UHCI: Checking HC state: Do reset...");
                BasicConsole.DelayOutput(1);
#endif

                USBSTS.Write_UInt16(UHCI_Consts.STS_MASK);
                Hardware.Devices.Timer.Default.Wait(1);
                USBCMD.Write_UInt16(UHCI_Consts.CMD_HCRESET);

                byte timeout = 50;
                while ((USBCMD.Read_UInt16() & UHCI_Consts.CMD_HCRESET) != 0)
                {
                    if (timeout == 0)
                    {
#if UHCI_TRACE
                        BasicConsole.WriteLine("UHCI: HC Reset timed out!");
                        BasicConsole.DelayOutput(1);
#endif
                        break;
                    }
                    Hardware.Devices.Timer.Default.Wait(10);
                    timeout--;
                }
                
#if UHCI_TRACE
                BasicConsole.WriteLine("UHCI: Checking HC state: Turning off interrupts and HC...");
                BasicConsole.DelayOutput(1);
#endif

                USBINTR.Write_UInt16(0); // switch off all interrupts
                USBCMD.Write_UInt16(0); // switch off the host controller
                
#if UHCI_TRACE
                BasicConsole.WriteLine("UHCI: Checking HC state: Disabling ports...");
                BasicConsole.DelayOutput(1);
#endif

                for (byte i = 0; i < RootPortCount; i++) // switch off the valid root ports
                {
                    PORTSC1.Write_UInt16(0, (ushort)(i * 2));
                }
            }

            // TODO: mutex for frame list
            
#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: Creating queue head...");
            BasicConsole.DelayOutput(1);
#endif

            UHCI_QueueHead_Struct* qh = (UHCI_QueueHead_Struct*)FOS_System.Heap.AllocZeroedAPB((uint)sizeof(UHCI_QueueHead_Struct), 32, "UHCI : ResetHC");
            qh->next = (UHCI_QueueHead_Struct*)UHCI_Consts.BIT_T;
            qh->transfer = (UHCI_qTD_Struct*)UHCI_Consts.BIT_T;
            qh->q_first = null;
            qh->q_last = null;
            qhPointer = qh;
            
#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: Setting up frame list entries...");
            BasicConsole.DelayOutput(1);
#endif

            for (ushort i = 0; i < 1024; i++)
            {
                FrameList[i] = UHCI_Consts.BIT_T;
            }
            
#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: Setting SOFMOD...");
            BasicConsole.DelayOutput(1);
#endif

            // define each millisecond one frame, provide physical address of frame list, and start at frame 0
            SOFMOD.Write_Byte(0x40); // SOF cycle time: 12000. For a 12 MHz SOF counter clock input, this produces a 1 ms Frame period.
            
#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: Setting frame base addr and frame num...");
            BasicConsole.DelayOutput(1);
#endif

            FRBASEADD.Write_UInt32((uint)VirtMemManager.GetPhysicalAddress(FrameList));
            FRNUM.Write_UInt16(0);
            
#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: Setting PCI PIRQ...");
            BasicConsole.DelayOutput(1);
#endif

            // set PIRQ
            pciDevice.WriteRegister16(UHCI_Consts.PCI_LEGACY_SUPPORT, UHCI_Consts.PCI_LEGACY_SUPPORT_PIRQ);
            
#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: Starting HC...");
            BasicConsole.DelayOutput(1);
#endif

            // start host controller and mark it configured with a 64-byte max packet
            USBSTS.Write_UInt16(UHCI_Consts.STS_MASK);
            USBINTR.Write_UInt16(UHCI_Consts.INT_MASK); // switch on all interrupts
            USBCMD.Write_UInt16((ushort)(UHCI_Consts.CMD_RS | UHCI_Consts.CMD_CF | UHCI_Consts.CMD_MAXP));
            
#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: Reset CSC ports...");
            BasicConsole.DelayOutput(1);
#endif

            for (byte i = 0; i < RootPortCount; i++) // reset the CSC of the valid root ports
            {
                PORTSC1.Write_UInt16(UHCI_Consts.PORT_CS_CHANGE, (ushort)(i * 2));
            }
            
#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: Forcing global resume...");
            BasicConsole.DelayOutput(1);
#endif

            USBSTS.Write_UInt16(UHCI_Consts.STS_MASK);
#if UHCI_TRACE
            BasicConsole.WriteLine("     - STS MASK set");
#endif
            USBCMD.Write_UInt16((ushort)(UHCI_Consts.CMD_RS | UHCI_Consts.CMD_CF | UHCI_Consts.CMD_MAXP | UHCI_Consts.CMD_FGR));
#if UHCI_TRACE
            BasicConsole.WriteLine("     - FGR issued");
#endif
            Hardware.Devices.Timer.Default.Wait(20);
            USBCMD.Write_UInt16((ushort)(UHCI_Consts.CMD_RS | UHCI_Consts.CMD_CF | UHCI_Consts.CMD_MAXP));
#if UHCI_TRACE
            BasicConsole.WriteLine("     - FGR cleared");            
            BasicConsole.DelayOutput(1);
#endif

            Hardware.Devices.Timer.Default.Wait(100);
            
#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: Getting run state...");
            BasicConsole.DelayOutput(1);
#endif

            run = (USBCMD.Read_UInt16() & UHCI_Consts.CMD_RS) != 0;

            

            if (!run)
            {
                BasicConsole.SetTextColour(BasicConsole.error_colour);
                BasicConsole.WriteLine("UHCI: Run/Stop not set!");
                BasicConsole.SetTextColour(BasicConsole.default_colour);
                BasicConsole.DelayOutput(5);
            }
            else
            {
                if ((USBSTS.Read_UInt16() & UHCI_Consts.STS_HCHALTED) == 0)
                {
                    Status = HCIStatus.Active;

                    EnablePorts(); // attaches the ports
                }
                else
                {
                    BasicConsole.SetTextColour(BasicConsole.error_colour);
                    BasicConsole.WriteLine("UHCI: HC Halted!");
                    BasicConsole.SetTextColour(BasicConsole.default_colour);
                    BasicConsole.DelayOutput(5);
                }
            }
        }        
Exemplo n.º 5
0
        protected void ResetHC()
        {
#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: ResetHC");
            BasicConsole.DelayOutput(5);
#endif

            //Processes.Scheduler.Disable();

            // http://www.lowlevel.eu/wiki/Universal_Host_Controller_Interface#Informationen_vom_PCI-Treiber_holen

            ushort legacySupport = pciDevice.ReadRegister16(UHCI_Consts.PCI_LEGACY_SUPPORT);
            pciDevice.WriteRegister16(UHCI_Consts.PCI_LEGACY_SUPPORT, UHCI_Consts.PCI_LEGACY_SUPPORT_STATUS); // resets support status bits in Legacy support register

            USBCMD.Write_UInt16(UHCI_Consts.CMD_GRESET);
            Hardware.Devices.Timer.Default.Wait(50);
            USBCMD.Write_UInt16(0);

            RootPortCount = (byte)(pciDevice.BaseAddresses[4].Size() / 2);
#if UHCI_TRACE
            BasicConsole.WriteLine(((FOS_System.String) "UHCI: RootPortCount=") + RootPortCount);
#endif
            for (byte i = 2; i < RootPortCount; i++)
            {
                if ((PORTSC1.Read_UInt16((ushort)(i * 2)) & UHCI_Consts.PORT_VALID) == 0 ||
                    (PORTSC1.Read_UInt16((ushort)(i * 2)) == 0xFFFF))
                {
                    RootPortCount = i;
                    break;
                }
            }
#if UHCI_TRACE
            BasicConsole.WriteLine(((FOS_System.String) "UHCI: RootPortCount=") + RootPortCount);
#endif

            if (RootPortCount > UHCI_Consts.PORTMAX)
            {
                RootPortCount = UHCI_Consts.PORTMAX;
            }
#if UHCI_TRACE
            BasicConsole.WriteLine(((FOS_System.String) "UHCI: RootPortCount=") + RootPortCount);
            BasicConsole.DelayOutput(1);
#endif

            RootPorts.Empty();
            for (byte i = 0; i < RootPortCount; i++)
            {
                RootPorts.Add(new HCPort()
                {
                    portNum = i
                });
            }

#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: Checking HC state: Get USBCMD...");
            BasicConsole.DelayOutput(1);
#endif

            ushort usbcmd = USBCMD.Read_UInt16();
#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: Checking HC state: Check...");
            BasicConsole.DelayOutput(1);
#endif
            if ((legacySupport & ~(UHCI_Consts.PCI_LEGACY_SUPPORT_STATUS | UHCI_Consts.PCI_LEGACY_SUPPORT_NO_CHG | UHCI_Consts.PCI_LEGACY_SUPPORT_PIRQ)) != 0 ||
                (usbcmd & UHCI_Consts.CMD_RS) != 0 ||
                (usbcmd & UHCI_Consts.CMD_CF) != 0 ||
                (usbcmd & UHCI_Consts.CMD_EGSM) == 0 ||
                (USBINTR.Read_UInt16() & UHCI_Consts.INT_MASK) != 0)
            {
#if UHCI_TRACE
                BasicConsole.WriteLine("UHCI: Checking HC state: Do reset...");
                BasicConsole.DelayOutput(1);
#endif

                USBSTS.Write_UInt16(UHCI_Consts.STS_MASK);
                Hardware.Devices.Timer.Default.Wait(1);
                USBCMD.Write_UInt16(UHCI_Consts.CMD_HCRESET);

                byte timeout = 50;
                while ((USBCMD.Read_UInt16() & UHCI_Consts.CMD_HCRESET) != 0)
                {
                    if (timeout == 0)
                    {
#if UHCI_TRACE
                        BasicConsole.WriteLine("UHCI: HC Reset timed out!");
                        BasicConsole.DelayOutput(1);
#endif
                        break;
                    }
                    Hardware.Devices.Timer.Default.Wait(10);
                    timeout--;
                }

#if UHCI_TRACE
                BasicConsole.WriteLine("UHCI: Checking HC state: Turning off interrupts and HC...");
                BasicConsole.DelayOutput(1);
#endif

                USBINTR.Write_UInt16(0); // switch off all interrupts
                USBCMD.Write_UInt16(0);  // switch off the host controller

#if UHCI_TRACE
                BasicConsole.WriteLine("UHCI: Checking HC state: Disabling ports...");
                BasicConsole.DelayOutput(1);
#endif

                for (byte i = 0; i < RootPortCount; i++) // switch off the valid root ports
                {
                    PORTSC1.Write_UInt16(0, (ushort)(i * 2));
                }
            }

            // TODO: mutex for frame list

#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: Creating queue head...");
            BasicConsole.DelayOutput(1);
#endif

            UHCI_QueueHead_Struct *qh = (UHCI_QueueHead_Struct *)FOS_System.Heap.AllocZeroedAPB((uint)sizeof(UHCI_QueueHead_Struct), 32, "UHCI : ResetHC");
            qh->next     = (UHCI_QueueHead_Struct *)UHCI_Consts.BIT_T;
            qh->transfer = (UHCI_qTD_Struct *)UHCI_Consts.BIT_T;
            qh->q_first  = null;
            qh->q_last   = null;
            qhPointer    = qh;

#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: Setting up frame list entries...");
            BasicConsole.DelayOutput(1);
#endif

            for (ushort i = 0; i < 1024; i++)
            {
                FrameList[i] = UHCI_Consts.BIT_T;
            }

#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: Setting SOFMOD...");
            BasicConsole.DelayOutput(1);
#endif

            // define each millisecond one frame, provide physical address of frame list, and start at frame 0
            SOFMOD.Write_Byte(0x40); // SOF cycle time: 12000. For a 12 MHz SOF counter clock input, this produces a 1 ms Frame period.

#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: Setting frame base addr and frame num...");
            BasicConsole.DelayOutput(1);
#endif

            FRBASEADD.Write_UInt32((uint)VirtMemManager.GetPhysicalAddress(FrameList));
            FRNUM.Write_UInt16(0);

#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: Setting PCI PIRQ...");
            BasicConsole.DelayOutput(1);
#endif

            // set PIRQ
            pciDevice.WriteRegister16(UHCI_Consts.PCI_LEGACY_SUPPORT, UHCI_Consts.PCI_LEGACY_SUPPORT_PIRQ);

#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: Starting HC...");
            BasicConsole.DelayOutput(1);
#endif

            // start host controller and mark it configured with a 64-byte max packet
            USBSTS.Write_UInt16(UHCI_Consts.STS_MASK);
            USBINTR.Write_UInt16(UHCI_Consts.INT_MASK); // switch on all interrupts
            USBCMD.Write_UInt16((ushort)(UHCI_Consts.CMD_RS | UHCI_Consts.CMD_CF | UHCI_Consts.CMD_MAXP));

#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: Reset CSC ports...");
            BasicConsole.DelayOutput(1);
#endif

            for (byte i = 0; i < RootPortCount; i++) // reset the CSC of the valid root ports
            {
                PORTSC1.Write_UInt16(UHCI_Consts.PORT_CS_CHANGE, (ushort)(i * 2));
            }

#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: Forcing global resume...");
            BasicConsole.DelayOutput(1);
#endif

            USBSTS.Write_UInt16(UHCI_Consts.STS_MASK);
#if UHCI_TRACE
            BasicConsole.WriteLine("     - STS MASK set");
#endif
            USBCMD.Write_UInt16((ushort)(UHCI_Consts.CMD_RS | UHCI_Consts.CMD_CF | UHCI_Consts.CMD_MAXP | UHCI_Consts.CMD_FGR));
#if UHCI_TRACE
            BasicConsole.WriteLine("     - FGR issued");
#endif
            Hardware.Devices.Timer.Default.Wait(20);
            USBCMD.Write_UInt16((ushort)(UHCI_Consts.CMD_RS | UHCI_Consts.CMD_CF | UHCI_Consts.CMD_MAXP));
#if UHCI_TRACE
            BasicConsole.WriteLine("     - FGR cleared");
            BasicConsole.DelayOutput(1);
#endif

            Hardware.Devices.Timer.Default.Wait(100);

#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: Getting run state...");
            BasicConsole.DelayOutput(1);
#endif

            run = (USBCMD.Read_UInt16() & UHCI_Consts.CMD_RS) != 0;



            if (!run)
            {
                BasicConsole.SetTextColour(BasicConsole.error_colour);
                BasicConsole.WriteLine("UHCI: Run/Stop not set!");
                BasicConsole.SetTextColour(BasicConsole.default_colour);
                BasicConsole.DelayOutput(5);
            }
            else
            {
                if ((USBSTS.Read_UInt16() & UHCI_Consts.STS_HCHALTED) == 0)
                {
                    Status = HCIStatus.Active;

                    EnablePorts(); // attaches the ports
                }
                else
                {
                    BasicConsole.SetTextColour(BasicConsole.error_colour);
                    BasicConsole.WriteLine("UHCI: HC Halted!");
                    BasicConsole.SetTextColour(BasicConsole.default_colour);
                    BasicConsole.DelayOutput(5);
                }
            }
        }