Beispiel #1
0
        /// <summary>
        /// Unset bit on port
        /// </summary>
        /// <param name="port">Port number</param>
        /// <param name="bit">Bit to unset</param>
        private static void unsetPortBit(UHCIController uhciDev, ushort port, ushort bit)
        {
            ushort status = PortIO.In16((ushort)(uhciDev.IOBase + port));

            status &= (ushort)~bit;
            PortIO.Out16((ushort)(uhciDev.IOBase + port), status);
        }
Beispiel #2
0
        /// <summary>
        /// IDE identify
        /// </summary>
        /// <param name="channel">Channel</param>
        /// <param name="drive">Slave or master?</param>
        /// <returns>The identification buffer</returns>
        private static byte[] identify(byte channel, byte drive)
        {
            // Select correct drive
            selectDrive(channel, drive);

            // Select base port for ATA drive
            ushort port = (channel == ATA_PRIMARY) ? ATA_PRIMARY_IO : ATA_SECONDARY_IO;

            // Set to first LBA
            PortIO.Out8((ushort)(port + ATA_REG_SECCNT), 0x00);
            PortIO.Out8((ushort)(port + ATA_REG_LBALO), 0x00);
            PortIO.Out8((ushort)(port + ATA_REG_LBAMID), 0x00);
            PortIO.Out8((ushort)(port + ATA_REG_LBAHI), 0x00);

            PortIO.Out8((ushort)(port + ATA_REG_CMD), ATA_CMD_IDENTIFY);

            // Check if a drive is found
            byte status = PortIO.In8((ushort)(port + ATA_REG_STATUS));

            if (status == 0)
            {
                return(null);
            }

            // Wait until drive is not busy anymore
            do
            {
                status = PortIO.In8((ushort)(port + ATA_REG_STATUS));
            }while ((status & ATA_STATUS_BSY) != 0);

            while (true)
            {
                status = PortIO.In8((ushort)(port + ATA_REG_STATUS));

                if ((status & ATA_STATUS_ERR) != 0)
                {
                    return(null);
                }

                if ((status & ATA_STATUS_DRQ) != 0)
                {
                    break;
                }
            }

            // Read data from ATA drive
            byte[] buffer = new byte[256];
            int    offset = 0;

            for (int i = 0; i < 128; i++)
            {
                ushort shrt = PortIO.In16((ushort)(port + ATA_REG_DATA));
                buffer[offset + 0] = (byte)(shrt >> 8);
                buffer[offset + 1] = (byte)(shrt);
                offset            += 2;
            }

            return(buffer);
        }
Beispiel #3
0
        /// <summary>
        /// Read sectors into the output buffer and return size in bytes
        /// </summary>
        /// <param name="num">The disk number</param>
        /// <param name="lba">Input LBA</param>
        /// <param name="size">Size in sectors</param>
        /// <param name="buffer">Output buffer</param>
        /// <returns>The amount of bytes read</returns>
        public static int ReadSector(int num, uint lba, byte size, byte[] buffer)
        {
            // The driver only supports up to 4 drives
            if (num >= 4)
            {
                return(0);
            }

            // Get IDE device from array
            IDE_Device device = Devices[num];

            if (!device.Exists)
            {
                return(0);
            }

            uint port  = device.BasePort;
            int  drive = device.Drive;

            int cmd = (drive == ATA_MASTER) ? 0xE0 : 0xF0;

            // Set Drive
            PortIO.Out8((ushort)(port + ATA_REG_DRIVE), (byte)(cmd | (byte)((lba >> 24) & 0x0F)));

            // Set PIO MODE
            PortIO.Out8((ushort)(port + ATA_REG_FEATURE), ATA_FEATURE_PIO);

            // Set size
            PortIO.Out8((ushort)(port + ATA_REG_SECCNT), size);

            // Set LBA
            PortIO.Out8((ushort)(port + ATA_REG_LBALO), (byte)lba);
            PortIO.Out8((ushort)(port + ATA_REG_LBAMID), (byte)(lba >> 8));
            PortIO.Out8((ushort)(port + ATA_REG_LBAHI), (byte)(lba >> 16));

            // Issue command
            PortIO.Out8((ushort)(port + ATA_REG_CMD), ATA_CMD_PIO_READ);

            // Wait till done
            poll(port);

            // Read data
            int offset = 0;

            for (int i = 0; i < size * 256; i++)
            {
                ushort data = PortIO.In16((ushort)(port + ATA_REG_DATA));
                buffer[offset + 0] = (byte)(data);
                buffer[offset + 1] = (byte)(data >> 8);
                offset            += 2;
            }

            return(size * 512);
        }
Beispiel #4
0
        /// <summary>
        /// Reset port
        /// </summary>
        /// <param name="port">Port num to reset</param>
        private static void resetPort(UHCIController uhciDev, ushort port)
        {
            /**
             * Set reset bit
             */
            setPortBit(uhciDev, port, PORTSC_RESET);

            /**
             * Wait for 60 ms
             */
            Tasking.CurrentTask.CurrentThread.Sleep(0, 60);

            /**
             * Unset reset bit
             */
            unsetPortBit(uhciDev, port, PORTSC_RESET);

            /**
             * Wait for atleast 150ms for link to go up
             */
            for (int i = 0; i < 15; i++)
            {
                Tasking.CurrentTask.CurrentThread.Sleep(0, 10);

                ushort status = PortIO.In16((ushort)(uhciDev.IOBase + port));

                /**
                 * Is it even connected?
                 */
                if (((status) & PORTSC_CUR_STAT) == 0)
                {
                    break;
                }

                /**
                 * Status changed?
                 */
                if (((status) & (PORTSC_STAT_CHNG | PORTSC_ENABLE_STAT)) > 0)
                {
                    unsetPortBit(uhciDev, port, PORTSC_STAT_CHNG | PORTSC_ENABLE_STAT);
                    continue;
                }

                /**
                 * Enabled?
                 */
                if ((status & PORTSC_CUR_ENABLE) > 0)
                {
                    break;
                }
            }
        }
Beispiel #5
0
        /// <summary>
        /// Reads the MAC address
        /// </summary>
        private static void ReadMac()
        {
            m_mac = new byte[6];

            uint tmp = PortIO.In16((ushort)(m_io_base + EPROM));

            m_mac[0] = (byte)((tmp) & 0xFF);
            m_mac[1] = (byte)((tmp >> 8) & 0xFF);
            tmp      = PortIO.In16((ushort)(m_io_base + EPROM2));
            m_mac[2] = (byte)((tmp) & 0xFF);
            m_mac[3] = (byte)((tmp >> 8) & 0xFF);
            tmp      = PortIO.In16((ushort)(m_io_base + EPROM4));
            m_mac[4] = (byte)((tmp) & 0xFF);
            m_mac[5] = (byte)((tmp >> 8) & 0xFF);
        }
Beispiel #6
0
        /// <summary>
        /// Probe usb devices on port
        /// </summary>
        /// <param name="uhciDev">The UHCI device</param>
        private static void probe(UHCIController uhciDev)
        {
            /**
             * UHCI only supports 2 ports, so just 2 :-)
             */
            for (int i = 0; i < 2; i++)
            {
                ushort port = (i == 0)? REG_PORTSC1 : REG_PORTSC2;

                resetPort(uhciDev, port);


                ushort status = PortIO.In16((ushort)(uhciDev.IOBase + port));

                /**
                 * Is the port even connected?
                 */
                if ((status & PORTSC_CUR_STAT) == 0)
                {
                    continue;
                }

                bool lowSpeed = ((status & PORTSC_LOW_SPEED) > 0);

                USBDevice dev = new USBDevice();
                dev.Controller       = uhciDev;
                dev.Control          = Control;
                dev.PrepareInterrupt = PrepareInterrupt;
                dev.TransferOne      = TransferOne;

                /**
                 * Root hub
                 */
                dev.Parent = null;
                dev.Port   = port;
                dev.State  = USBDeviceState.ATTACHED;
                dev.Speed  = (lowSpeed) ? USBDeviceSpeed.LOW_SPEED : USBDeviceSpeed.HIGH_SPEED;

                if (!dev.Init())
                {
                    Heap.Free(dev);
                }
            }
        }
Beispiel #7
0
        public static int AcpiOsReadPort(ulong Address, uint *Value, uint Width)
        {
            if (Width == 8)
            {
                *Value = PortIO.In8((ushort)Address);
            }
            else if (Width == 16)
            {
                *Value = PortIO.In16((ushort)Address);
            }
            else if (Width == 32)
            {
                *Value = PortIO.In32((ushort)Address);
            }
            else
            {
                return(AE_BAD_PARAMETER);
            }

            return(AE_OK);
        }
Beispiel #8
0
        private static void SoftwareReset()
        {
            // RESET
            PortIO.In32((ushort)(m_io_base + 0x18));
            PortIO.In16((ushort)(m_io_base + 0x14));

            Sleep(5);

            // SET BCR
            PortIO.Out32((ushort)(m_io_base + REG_RDP), 0);

            // Enable 32bit :)
            writeBCR(20, 1);

            // sws style 2 please
            uint csr58 = readCSR(58);

            csr58 &= 0xFFF0;
            csr58 |= 2;
            writeCSR(58, csr58);
        }
Beispiel #9
0
        /// <summary>
        /// IRQ Handler
        /// </summary>
        /// <returns>If we handled the irq</returns>
        private static bool handler()
        {
            ushort sr = PortIO.In16((ushort)(m_nabmbar + REG_SR));

            if ((sr & SR_LVBCI) > 0)
            {
                PortIO.Out16((ushort)(m_nabmbar + REG_SR), SR_LVBCI);
            }
            else if ((sr & SR_BCIS) > 0)
            {
                // Load next one already
                int next = m_lvi + 2;
                if (next >= BDL_COUNT)
                {
                    next -= BDL_COUNT;
                }

                AudioFS.RequestBuffer(AudioFS.BufferSize, m_bufs[next]);

                // Set current one
                m_lvi++;
                if (m_lvi == BDL_COUNT)
                {
                    m_lvi = 0;
                }

                PortIO.Out8((ushort)(m_nabmbar + REG_LVI), (byte)m_lvi);
                PortIO.Out16((ushort)(m_nabmbar + REG_SR), SR_BCIS);
            }
            else if ((sr & SR_FIFOE) > 0)
            {
                PortIO.Out16((ushort)(m_nabmbar + REG_SR), SR_FIFOE);
            }
            else
            {
                return(false);
            }

            return(true);
        }
Beispiel #10
0
        /// <summary>
        /// Handle interrupt
        /// </summary>
        /// <returns>If this IRQ was handled by the device</returns>
        private static unsafe bool handler()
        {
            ushort ISR = PortIO.In16((ushort)(m_io_base + REG_ISR));

            if ((ISR & ISR_TOK) > 0)
            {
                // We need to read every TX
                for (int i = 0; i < 4; i++)
                {
                    if (((int)PortIO.In32((ushort)(m_io_base + REG_TSD0 + (i * 4))) & TX_STATUS_OK) > 0)
                    {
                        m_mutexes[i].Unlock();
                    }
                }
            }

#if RTL_DEBUG
            if ((ISR & ISR_TER) > 0)
            {
                Console.WriteLine("[RTL8139] Transmit error!");
            }

            if ((ISR & ISR_RER) > 0)
            {
                Console.WriteLine("[RTL8139] Receive error!");
            }
#endif

            if ((ISR & ISR_ROK) > 0)
            {
                HandlePackets();
            }

            PortIO.Out16((ushort)(m_io_base + REG_ISR), ISR);

            return(true);
        }