Esempio n. 1
0
        public static void Test_QueueHeadWrapper()
        {
            FOS_System.String testName = "Queue Head Wrapper";
            DBGMSG(testName, "START");

            errors = 0;
            warnings = 0;

            EHCI_QueueHead qh = new EHCI_QueueHead();
            try
            {
                byte* pQH = (byte*)qh.queueHead;

                //Verifications done via two methods:
                //  1. Check value from pointer & manual shifting to confirm set properly
                //  2. Check value from "get" method to confirm reading properly
                //  3. For boolean types, also test & verify setting to false!

                qh.Active = true;
                if ((pQH[0x18u] & 0x80u) == 0)
                {
                    DBGERR(testName, "Active - Failed to set to true.");
                }
                else
                {
                    if (!qh.Active)
                    {
                        DBGERR(testName, "Active - Failed to read as true.");
                    }
                    else
                    {
                        pQH[0x18u] = 0xFF;
                        qh.Active = false;
                        if ((pQH[0x18u] & 0x80u) != 0)
                        {
                            DBGERR(testName, "Active - Failed to set to false.");
                        }
                        else
                        {
                            if (qh.Active)
                            {
                                DBGERR(testName, "Active - Failed to read as false.");
                            }
                        }
                    }
                }

                qh.ControlEndpointFlag = true;
                if ((pQH[0x07u] & 0x08u) == 0)
                {
                    DBGERR(testName, "ControlEndpointFlag - Failed to set to true.");
                }
                else
                {
                    if (!qh.ControlEndpointFlag)
                    {
                        DBGERR(testName, "ControlEndpointFlag - Failed to read as true.");
                    }
                    else
                    {
                        pQH[0x07u] = 0xFF;
                        qh.ControlEndpointFlag = false;
                        if ((pQH[0x07u] & 0x08u) != 0)
                        {
                            DBGERR(testName, "ControlEndpointFlag - Failed to set to false.");
                        }
                        else
                        {
                            if (qh.ControlEndpointFlag)
                            {
                                DBGERR(testName, "ControlEndpointFlag - Failed to read as false.");
                            }
                        }
                    }
                }

                qh.CurrentqTDPointer = (EHCI_qTD_Struct*)0xDEADBEFFu;
                //- Read back should equal 0xDEADBEE0
                if ((pQH[0x0Cu] & 0xF0u) != 0xF0u ||
                     pQH[0x0Du]          != 0xBEu ||
                     pQH[0x0Eu]          != 0xADu ||
                     pQH[0x0Fu]          != 0xDEu)
                {
                    DBGERR(testName, "CurrentqTDPointer - Failed to set.");
                }
                else
                {
                    if ((uint)qh.CurrentqTDPointer != 0xDEADBEF0u)
                    {
                        DBGERR(testName, "CurrentqTDPointer - Failed to read.");
                    }
                }

                qh.DataToggleControl = true;
                if ((pQH[0x05u] & 0x40u) == 0)
                {
                    DBGERR(testName, "DataToggleControl - Failed to set to true.");
                }
                else
                {
                    if (!qh.DataToggleControl)
                    {
                        DBGERR(testName, "DataToggleControl - Failed to read as true.");
                    }
                    else
                    {
                        pQH[0x05u] = 0xFF;
                        qh.DataToggleControl = false;
                        if ((pQH[0x05u] & 0x40u) != 0)
                        {
                            DBGERR(testName, "DataToggleControl - Failed to set to false.");
                        }
                        else
                        {
                            if (qh.DataToggleControl)
                            {
                                DBGERR(testName, "DataToggleControl - Failed to read as false.");
                            }
                        }
                    }
                }

                qh.DeviceAddress = 0xDE;
                if ((pQH[0x04u] & 0x7Fu) != 0x5Eu)
                {
                    DBGERR(testName, "DeviceAddress - Failed to set.");
                }
                else
                {
                    if ((uint)qh.DeviceAddress != 0x5Eu)
                    {
                        DBGERR(testName, "DeviceAddress - Failed to read.");
                    }
                }

                qh.EndpointNumber = 0xBF;
                //Shift!
                if ((pQH[0x05u] & 0x0Fu) != 0x0Fu)
                {
                    DBGERR(testName, "EndpointNumber - Failed to set.");
                }
                else
                {
                    if ((uint)qh.EndpointNumber != 0x0Fu)
                    {
                        DBGERR(testName, "EndpointNumber - Failed to read.");
                    }
                }

                qh.EndpointSpeed = 0xB3;
                //Shift!
                if ((pQH[0x05u] & 0x30u) != 0x30u)
                {
                    DBGERR(testName, "EndpointSpeed - Failed to set.");
                }
                else
                {
                    if ((uint)qh.EndpointSpeed != 0x03u)
                    {
                        DBGERR(testName, "EndpointSpeed - Failed to read.");
                    }
                }

                qh.HeadOfReclamationList = true;
                if ((pQH[0x05u] & 0x80u) == 0)
                {
                    DBGERR(testName, "HeadOfReclamationList - Failed to set to true.");
                }
                else
                {
                    if (!qh.HeadOfReclamationList)
                    {
                        DBGERR(testName, "HeadOfReclamationList - Failed to read as true.");
                    }
                    else
                    {
                        pQH[0x05u] = 0xFF;
                        qh.HeadOfReclamationList = false;
                        if ((pQH[0x05u] & 0x80u) != 0)
                        {
                            DBGERR(testName, "HeadOfReclamationList - Failed to set to false.");
                        }
                        else
                        {
                            if (qh.HeadOfReclamationList)
                            {
                                DBGERR(testName, "HeadOfReclamationList - Failed to read as false.");
                            }
                        }
                    }
                }

                qh.HighBandwidthPipeMultiplier = 0xDF;
                //Shift!
                if ((pQH[0x0Bu] & 0xC0u) != 0xC0u)
                {
                    DBGERR(testName, "HighBandwidthPipeMultiplier - Failed to set.");
                }
                else
                {
                    if ((uint)qh.HighBandwidthPipeMultiplier != 0x03u)
                    {
                        DBGERR(testName, "HighBandwidthPipeMultiplier - Failed to read.");
                    }
                }

                qh.HorizontalLinkPointer = (EHCI_QueueHead_Struct*)0xDEADBEFE;
                if ((pQH[0x00u] & 0xE0u) != 0xE0u ||
                     pQH[0x01u]          != 0xBEu ||
                     pQH[0x02u]          != 0xADu ||
                     pQH[0x03u]          != 0xDEu)
                {
                    DBGERR(testName, "HorizontalLinkPointer - Failed to set.");
                }
                else
                {
                    if ((uint)qh.HorizontalLinkPointer != 0xDEADBEE0u)
                    {
                        DBGERR(testName, "HorizontalLinkPointer - Failed to read.");
                    }
                }

                qh.HubAddr = 0xBE;
                //Shift!
                if ((pQH[0x0Au] & 0x7Fu) != 0x3Eu)
                {
                    DBGERR(testName, "HubAddr - Failed to set.");
                }
                else
                {
                    if ((uint)qh.HubAddr != 0x3Eu)
                    {
                        DBGERR(testName, "HubAddr - Failed to read.");
                    }
                }

                qh.InactiveOnNextTransaction = true;
                if ((pQH[0x04u] & 0x80u) == 0)
                {
                    DBGERR(testName, "InactiveOnNextTransaction - Failed to set to true.");
                }
                else
                {
                    if (!qh.InactiveOnNextTransaction)
                    {
                        DBGERR(testName, "InactiveOnNextTransaction - Failed to read as true.");
                    }
                    else
                    {
                        pQH[0x04u] = 0xFF;
                        qh.InactiveOnNextTransaction = false;
                        if ((pQH[0x04u] & 0x80u) != 0)
                        {
                            DBGERR(testName, "InactiveOnNextTransaction - Failed to set to false.");
                        }
                        else
                        {
                            if (qh.InactiveOnNextTransaction)
                            {
                                DBGERR(testName, "InactiveOnNextTransaction - Failed to read as false.");
                            }
                        }
                    }
                }

                qh.InterruptScheduleMask = 0xFE;
                //Shift!
                if (pQH[0x08u] != 0xFEu)
                {
                    DBGERR(testName, "InterruptScheduleMask - Failed to set.");
                }
                else
                {
                    if ((uint)qh.InterruptScheduleMask != 0xFEu)
                    {
                        DBGERR(testName, "InterruptScheduleMask - Failed to read.");
                    }
                }

                qh.MaximumPacketLength = 0xDEAD;
                //Shift!
                if ( pQH[0x06u]          != 0xADu ||
                    (pQH[0x07u] & 0x07u) != 0x06u)
                {
                    DBGERR(testName, "MaximumPacketLength - Failed to set.");
                }
                else
                {
                    if ((uint)qh.MaximumPacketLength != 0x06ADu)
                    {
                        DBGERR(testName, "MaximumPacketLength - Failed to read.");
                    }
                }

                qh.NakCountReload = 0xFF;
                //Shift!
                if ((pQH[0x07u] & 0xF0u) != 0xF0u)
                {
                    DBGERR(testName, "NakCountReload - Failed to set.");
                }
                else
                {
                    if ((uint)qh.NakCountReload != 0x0Fu)
                    {
                        DBGERR(testName, "NakCountReload - Failed to read.");
                    }
                }

                qh.NextqTDPointer = (EHCI_qTD_Struct*)0xDEADBEFF;
                //- Read back should equal 0xDEADBEE0
                if ((pQH[0x10u] & 0xF0u) != 0xF0u ||
                     pQH[0x11u] != 0xBEu ||
                     pQH[0x12u] != 0xADu ||
                     pQH[0x13u] != 0xDEu)
                {
                    DBGERR(testName, "NextqTDPointer - Failed to set.");
                }
                else
                {
                    if ((uint)qh.NextqTDPointer != 0xDEADBEF0u)
                    {
                        DBGERR(testName, "NextqTDPointer - Failed to read.");
                    }
                }

                qh.NextqTDPointerTerminate = true;
                if ((pQH[0x10u] & 0x01u) == 0)
                {
                    DBGERR(testName, "NextqTDPointerTerminate - Failed to set to true.");
                }
                else
                {
                    if (!qh.NextqTDPointerTerminate)
                    {
                        DBGERR(testName, "NextqTDPointerTerminate - Failed to read as true.");
                    }
                    else
                    {
                        pQH[0x10u] = 0xFF;
                        qh.NextqTDPointerTerminate = false;
                        if ((pQH[0x10u] & 0x01u) != 0)
                        {
                            DBGERR(testName, "NextqTDPointerTerminate - Failed to set to false.");
                        }
                        else
                        {
                            if (qh.NextqTDPointerTerminate)
                            {
                                DBGERR(testName, "NextqTDPointerTerminate - Failed to read as false.");
                            }
                        }
                    }
                }

                qh.PortNumber = 0xFF;
                //Shift!
                if ((pQH[0x0Au] & 0x80u) != 0x80u ||
                    (pQH[0x0Bu] & 0x3Fu) != 0x3Fu)
                {
                    DBGERR(testName, "PortNumber - Failed to set.");
                }
                else
                {
                    if ((uint)qh.PortNumber != 0x7Fu)
                    {
                        DBGERR(testName, "PortNumber - Failed to read.");
                    }
                }

                qh.SplitCompletionMask = 0xBE;
                //Shift!
                if (pQH[0x09u] != 0xBEu)
                {
                    DBGERR(testName, "SplitCompletionMask - Failed to set.");
                }
                else
                {
                    if ((uint)qh.SplitCompletionMask != 0xBEu)
                    {
                        DBGERR(testName, "SplitCompletionMask - Failed to read.");
                    }
                }

                qh.Terminate = true;
                if ((pQH[0x00u] & 0x01u) == 0)
                {
                    DBGERR(testName, "Terminate - Failed to set to true.");
                }
                else
                {
                    if (!qh.Terminate)
                    {
                        DBGERR(testName, "Terminate - Failed to read as true.");
                    }
                    else
                    {
                        pQH[0x00u] = 0xFF;
                        qh.Terminate = false;
                        if ((pQH[0x00u] & 0x01u) != 0)
                        {
                            DBGERR(testName, "Terminate - Failed to set to false.");
                        }
                        else
                        {
                            if (qh.Terminate)
                            {
                                DBGERR(testName, "Terminate - Failed to read as false.");
                            }
                        }
                    }
                }

                qh.Type = 0xFF;
                //Shift!
                if ((pQH[0x00u] & 0x06u) != 0x06u)
                {
                    DBGERR(testName, "Type - Failed to set.");
                }
                else
                {
                    if ((uint)qh.Type != 0x03u)
                    {
                        DBGERR(testName, "Type - Failed to read.");
                    }
                }

            }
            catch
            {
                errors++;
                BasicConsole.SetTextColour(BasicConsole.warning_colour);
                BasicConsole.WriteLine(ExceptionMethods.CurrentException.Message);
                BasicConsole.SetTextColour(BasicConsole.default_colour);
            }
            finally
            {
                qh.Free();
            }

            if (errors > 0)
            {
                DBGERR(testName, ((FOS_System.String)"Test failed! Errors: ") + errors + " Warnings: " + warnings);
            }
            else
            {
                if (warnings > 0)
                {
                    DBGWRN(testName, ((FOS_System.String)"Test passed with warnings: ") + warnings);
                }
                else
                {
                    DBGMSG(testName, "Test passed.");
                }
            }

            DBGMSG(testName, "END");

            BasicConsole.DelayOutput(1);
        }
Esempio n. 2
0
 /// <summary>
 /// Initialises a queue head - memory must already be allocated.
 /// </summary>
 /// <param name="headPtr">A pointer to the queue head structure to initialise.</param>
 /// <param name="horizPtr">
 /// The virtual address of the next queue head in the list (or the first queue head since the 
 /// async queue is a circular buffer). This is translated into the physical address internally.
 /// </param>
 /// <param name="firstQTD">A pointer to the first qTD of the queue head.</param>
 /// <param name="H">The Head of Reclamation list flag.</param>
 /// <param name="deviceAddr">The address of the USB device to which this queue head belongs.</param>
 /// <param name="endpoint">The endpoint number of the USB device to which this queue head belongs.</param>
 /// <param name="maxPacketSize">The maximum packet size to use when transferring.</param>
 protected void InitQH(EHCI_QueueHead_Struct* headPtr, EHCI_QueueHead_Struct* horizPtr, EHCI_qTD_Struct* firstQTD, bool H, byte deviceAddr,
                            byte endpoint, ushort maxPacketSize)
 {
     EHCI_QueueHead head = new EHCI_QueueHead(headPtr);
     head.HorizontalLinkPointer = (EHCI_QueueHead_Struct*)VirtMemManager.GetPhysicalAddress(horizPtr);
     head.Type = 0x1;        // Types:  00b iTD,   01b QH,   10b siTD,   11b FSTN
     head.Terminate = false;
     head.DeviceAddress = deviceAddr;         // The device address
     head.InactiveOnNextTransaction = false;
     head.EndpointNumber = endpoint;       // endpoint 0 contains Device infos such as name
     head.EndpointSpeed = 2;              // 00b = full speed; 01b = low speed; 10b = high speed
     head.DataToggleControl = true;              // get the Data Toggle bit out of the included qTD
     head.HeadOfReclamationList = H;              // mark a queue head as being the head of the reclaim list
     head.MaximumPacketLength = maxPacketSize;     // 64 byte for a control transfer to a high speed device
     head.ControlEndpointFlag = false;              // only used if endpoint is a control endpoint and not high speed
     head.NakCountReload = 0;              // this value is used by EHCI to reload the Nak Counter field. 0=ignores NAK counter.
     head.InterruptScheduleMask = 0;              // not used for async schedule
     head.SplitCompletionMask = 0;              // unused if (not low/full speed and in periodic schedule)
     head.HubAddr = 0;              // unused if high speed (Split transfer)
     head.PortNumber = 0;              // unused if high speed (Split transfer)
     head.HighBandwidthPipeMultiplier = 1;              // 1-3 transaction per micro-frame, 0 means undefined results
     if (firstQTD == null)
     {
         head.NextqTDPointer = null;
         head.NextqTDPointerTerminate = true;
     }
     else
     {
         head.NextqTDPointer = (EHCI_qTD_Struct*)VirtMemManager.GetPhysicalAddress(firstQTD);
         head.NextqTDPointerTerminate = false;
     }
 }
Esempio n. 3
0
        //SetupTransfer
        //SETUPTransaction
        //INTransaction
        //OUTTransaction
        //IssueTransfer
        //CreateQTD_SETUP
        //CreateQTD_IO
        //Create_QH
        public void Test_Create_QH()
        {
            FOS_System.String testName = "Queue Transfer Descrip";
            EHCITesting.DBGMSG(testName, "START");

            EHCITesting.errors = 0;
            EHCITesting.warnings = 0;

            EHCI_QueueHead qh = new EHCI_QueueHead();
            EHCI_QueueHead_Struct* pQH = qh.queueHead;
            try
            {
                CreateQH(pQH, 0xDEADBEEFu, (EHCI_qTD_Struct*)0x12345678u, true, 0xFE, 0xED, 0x1234);

                //Confirm values (other tests check that these get/set properties work properly)

            }
            catch
            {
                EHCITesting.errors++;
                BasicConsole.SetTextColour(BasicConsole.warning_colour);
                BasicConsole.WriteLine(ExceptionMethods.CurrentException.Message);
                BasicConsole.SetTextColour(BasicConsole.default_colour);
            }
            finally
            {
                qh.Free();
            }

            if (EHCITesting.errors > 0)
            {
                EHCITesting.DBGERR(testName, ((FOS_System.String)"Test failed! Errors: ") + EHCITesting.errors + " Warnings: " + EHCITesting.warnings);
            }
            else
            {
                if (EHCITesting.warnings > 0)
                {
                    EHCITesting.DBGWRN(testName, ((FOS_System.String)"Test passed with warnings: ") + EHCITesting.warnings);
                }
                else
                {
                    EHCITesting.DBGMSG(testName, "Test passed.");
                }
            }

            EHCITesting.DBGMSG(testName, "END");

            BasicConsole.DelayOutput(4);
        }
Esempio n. 4
0
        /// <summary>
        /// Adds a transfer for the async schedule.
        /// </summary>
        /// <param name="transfer">The transfer to add.</param>
        protected void AddToAsyncSchedule(USBTransfer transfer)
        {
            // Set the expected number of USB Interrupts to 1
            //  1 because we expect one and only one for the last transaction of the transfer
            //  which we flagged to Interrupt On Complete in IssueTransfer.
            USBIntCount = 1;

            // If the schedule is disabled:
            // Section 2.3.2 of Intel EHCI Spec
            if ((USBSTS & EHCI_Consts.STS_AsyncEnabled) == 0)
            {
                // Enable / start the async schedule
                EnableAsyncSchedule();
            }
            
            // Save the old tail queue head (which may not be the idle queue head) (save in a wrapper)
            EHCI_QueueHead oldTailQH = new EHCI_QueueHead(TailQueueHead);
            // The new queue head will now be end of the queue
            TailQueueHead = (EHCI_QueueHead_Struct*)transfer.underlyingTransferData;

            // Create wrappers for the idle and tail queue heads.
            EHCI_QueueHead idleQH = new EHCI_QueueHead(IdleQueueHead);
            EHCI_QueueHead tailQH = new EHCI_QueueHead(TailQueueHead);
            // Create the ring. Link the new queue head with idleQH (which is always the head of the queue)
            tailQH.HorizontalLinkPointer = (EHCI_QueueHead_Struct*)VirtMemManager.GetPhysicalAddress(IdleQueueHead);
            // Insert the queue head into the queue as an element behind old queue head
            oldTailQH.HorizontalLinkPointer = (EHCI_QueueHead_Struct*)VirtMemManager.GetPhysicalAddress(TailQueueHead);

            int timeout = 100;
            while (USBIntCount > 0 && (HostSystemErrors == 0) && !IrrecoverableError && --timeout > 0)
            {
                Kernel.Processes.SystemCalls.SleepThread(50);
#if EHCI_TRACE
                if (timeout % 10 == 0)
                {
                    BasicConsole.WriteLine("Waiting for transfer to complete...");
                }
#endif
            }

#if EHCI_TRACE
            if (timeout == 0)
            {
                BasicConsole.WriteLine("Transfer timed out.");
            }
#endif

            // Restore the link of the old tail queue head to the idle queue head
            oldTailQH.HorizontalLinkPointer = (EHCI_QueueHead_Struct*)VirtMemManager.GetPhysicalAddress(IdleQueueHead);
            // Queue head done. 
            // Because nothing else touches the async queue and this method is a synchronous method, 
            //  the idle queue head will now always be the end of the queue again.
            TailQueueHead = oldTailQH.queueHead;
        }