Ejemplo n.º 1
0
        protected void InterruptHandler()
        {
#if UHCI_TRACE
            BasicConsole.SetTextColour(BasicConsole.warning_colour);
            BasicConsole.WriteLine("UHCI: Interrupt handler");
            BasicConsole.SetTextColour(BasicConsole.default_colour);
            BasicConsole.DelayOutput(20);
#endif

            ushort val = USBSTS.Read_UInt16();

            if (val == 0) // Interrupt came from another UHCI device
            {
                return;
            }

            //if ((val & UHCI_Consts.STS_USBINT) == 0)
            //{
            //    //printf("\nUSB UHCI %u: ", u->num);
            //}

            //textColor(IMPORTANT);

#if UHCI_TRACE
            BasicConsole.SetTextColour(BasicConsole.warning_colour);
#endif

            if ((val & UHCI_Consts.STS_USBINT) != 0)
            {
#if UHCI_TRACE
                BasicConsole.WriteLine(((FOS_System.String) "UHCI Frame: ") + FRNUM.Read_UInt16() + " - USB transaction completed");
#endif
                USBSTS.Write_UInt16(UHCI_Consts.STS_USBINT); // reset interrupt
                TransactionsCompleted++;
            }

            if ((val & UHCI_Consts.STS_RESUME_DETECT) != 0)
            {
#if UHCI_TRACE
                BasicConsole.WriteLine("UHCI: Resume Detect");
#endif
                USBSTS.Write_UInt16(UHCI_Consts.STS_RESUME_DETECT); // reset interrupt
            }

#if UHCI_TRACE
            BasicConsole.SetTextColour(BasicConsole.error_colour);
#endif

            if ((val & UHCI_Consts.STS_HCHALTED) != 0)
            {
#if UHCI_TRACE
                BasicConsole.WriteLine("UHCI: Host Controller Halted");
#endif
                USBSTS.Write_UInt16(UHCI_Consts.STS_HCHALTED); // reset interrupt
            }

            if ((val & UHCI_Consts.STS_HC_PROCESS_ERROR) != 0)
            {
#if UHCI_TRACE
                BasicConsole.WriteLine("UHCI: Host Controller Process Error");
#endif
                USBSTS.Write_UInt16(UHCI_Consts.STS_HC_PROCESS_ERROR); // reset interrupt
            }

            if ((val & UHCI_Consts.STS_USB_ERROR) != 0)
            {
#if UHCI_TRACE
                BasicConsole.WriteLine("UHCI: USB Error");
#endif
                USBSTS.Write_UInt16(UHCI_Consts.STS_USB_ERROR); // reset interrupt
            }

            if ((val & UHCI_Consts.STS_HOST_SYSTEM_ERROR) != 0)
            {
#if UHCI_TRACE
                BasicConsole.WriteLine("UHCI: Host System Error");
#endif
                USBSTS.Write_UInt16(UHCI_Consts.STS_HOST_SYSTEM_ERROR); // reset interrupt
            }

#if UHCI_TRACE
            BasicConsole.SetTextColour(BasicConsole.default_colour);
#endif
        }
Ejemplo n.º 2
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);
                }
            }
        }