Example #1
0
        /// <summary>
        /// Handles incoming packets
        /// </summary>
        private static unsafe void HandlePackets()
        {
            /**
             * While buffer is not empty...
             */
            while ((PortIO.In8((ushort)(m_io_base + REG_CMD)) & CMD_BUFE) == 0)
            {
                uint offset = m_curRX % 8192;

                uint status = *(uint *)(m_buffer + offset);
                uint size   = (status >> 16);
                status &= 0xFFFF;

                // Add packet
                byte[] buffer = new byte[size];
                Memory.Memcpy(Util.ObjectToVoidPtr(buffer), &m_buffer[offset + 4], (int)size);
                Network.QueueReceivePacket(buffer, (int)size);
                Heap.Free(buffer);

                // Next packet and align
                m_curRX += 4 + size;
                m_curRX  = (uint)((m_curRX + 3) & ~3);
                if (m_curRX > 8192)
                {
                    m_curRX -= 8192;
                }

                // Update receive pointer
                PortIO.Out16((ushort)(m_io_base + REG_CAPR), (ushort)(m_curRX - 16));
            }
        }
Example #2
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);
        }
Example #3
0
        /// <summary>
        /// Driver initialization
        /// </summary>
        /// <param name="dev">PCI Device</param>
        private static void initHandler(PciDevice dev)
        {
            m_dev     = dev;
            m_nambar  = (ushort)dev.BAR0.Address;
            m_nabmbar = (ushort)dev.BAR1.Address;

            // Set IRQ handler and bus mastering and I/O space
            Pci.SetInterruptHandler(dev, handler);
            Pci.EnableBusMastering(dev);
            Pci.EnableIOSpace(dev);

            // Enable all interrupts
            PortIO.Out8((ushort)(m_nabmbar + REG_CR), (CR_FEIE | CR_IOCE | CR_LVBIE));

            // Volume
            ushort volume = 0x03 | (0x03 << 8);

            PortIO.Out16((ushort)(m_nambar + MASTER_VOLUME), volume);
            PortIO.Out16((ushort)(m_nambar + PCM_OUT_VOLUME), volume);

            // Buffers
            m_bdls = new BDL_Entry[BDL_COUNT];
            m_bufs = new ushort[BDL_COUNT][];
            for (int i = 0; i < BDL_COUNT; i++)
            {
                m_bufs[i] = new ushort[AudioFS.BufferSize];
                fixed(void *ptr = m_bufs[i])
                {
                    m_bdls[i].pointer = Paging.GetPhysicalFromVirtual(ptr);
                }

                // Length and interrupt-on-clear
                m_bdls[i].cl  = AudioFS.BufferSize & 0xFFFF;
                m_bdls[i].cl |= CL_IOC;
            }

            // Tell BDL location
            fixed(void *ptr = m_bdls)
            {
                PortIO.Out32((ushort)(m_nabmbar + REG_BDBAR), (uint)Paging.GetPhysicalFromVirtual(ptr));
            }

            // Set last valid index
            m_lvi = 3;
            PortIO.Out8((ushort)(m_nabmbar + REG_LVI), (byte)m_lvi);

            // Set audio to playing
            PortIO.Out8((ushort)(m_nabmbar + REG_CR), (byte)(PortIO.In8((ushort)(m_nabmbar + REG_CR)) | CR_RPBM));

            Console.WriteLine("[AC97] Initialized");
        }
Example #4
0
        public static int AcpiOsWritePort(ulong Address, uint Value, uint Width)
        {
            if (Width == 8)
            {
                PortIO.Out8((ushort)Address, (byte)Value);
            }
            else if (Width == 16)
            {
                PortIO.Out16((ushort)Address, (ushort)Value);
            }
            else if (Width == 32)
            {
                PortIO.Out32((ushort)Address, Value);
            }
            else
            {
                return(AE_BAD_PARAMETER);
            }

            return(AE_OK);
        }
Example #5
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);
        }
Example #6
0
        /// <summary>
        /// Writing operation
        /// </summary>
        /// <param name="action">The audio action</param>
        /// <param name="value">The value to write</param>
        private static void Writer(AudioActions action, uint value)
        {
            if (action == AudioActions.Master)
            {
                value = ~value;

                // It's a 6bit value!
                value >>= 26;

                ushort encoded = (ushort)(value | (value << 8));
                PortIO.Out16((ushort)(m_nambar + MASTER_VOLUME), encoded);
            }
            else if (action == AudioActions.PCM_OUT)
            {
                value = ~value;

                // It's a 5 bit value!
                value >>= 27;

                ushort encoded = (ushort)(value | (value << 8));
                PortIO.Out16((ushort)(m_nambar + PCM_OUT_VOLUME), encoded);
            }
        }
Example #7
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);
        }
Example #8
0
        /// <summary>
        /// Write sector to drive and return size in bytes
        /// </summary>
        /// <param name="num">The disk number</param>
        /// <param name="lba">Input LBA</param>
        /// <param name="size">Output size in sectors</param>
        /// <param name="buffer">Input buffer</param>
        /// <returns>The amount of bytes written</returns>
        public static int WriteSector(int num, uint lba, byte size, byte[] buffer)
        {
            // The driver only supports up to 4 drivers
            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_WRITE);

            // Wait till done
            poll(port);

            // Wait for 400ns
            wait400ns(port);

            // Write data
            for (int i = 0; i < size * 256; i++)
            {
                int    pos  = i * 2;
                ushort shrt = (ushort)((buffer[pos + 1] << 8) | buffer[pos]);

                PortIO.Out16((ushort)(port + ATA_REG_DATA), shrt);
            }

            // Flush data
            PortIO.Out8((ushort)(port + ATA_REG_CMD), ATA_CMD_FLUSH);

            // Wait till done
            byte status;

            do
            {
                status = PortIO.In8((ushort)(port + ATA_REG_STATUS));
            }while ((status & ATA_STATUS_BSY) > 0);

            return(size * 512);
        }
Example #9
0
 /// <summary>
 /// Set interrupt mask
 /// </summary>
 private static void setInterruptMask(ushort value)
 {
     PortIO.Out16((ushort)(m_io_base + REG_IMR), value);
 }
Example #10
0
        private static void initDevice(PciDevice dev)
        {
            if ((dev.BAR4.flags & Pci.BAR_IO) == 0)
            {
                Console.WriteLine("[UHCI] Only Portio supported");
            }

            Pci.EnableBusMastering(dev);

            UHCIController uhciDev = new UHCIController();

            uhciDev.IOBase = (ushort)dev.BAR4.Address;
            uhciDev.Poll   = Poll;


            Console.Write("[UHCI] Initalize at 0x");
            Console.WriteHex(uhciDev.IOBase);
            Console.WriteLine("");

            uhciDev.FrameList     = (int *)Heap.AlignedAlloc(0x1000, sizeof(int) * 1024);
            uhciDev.QueueHeadPool = (UHCIQueueHead *)Heap.AlignedAlloc(0x1000, sizeof(UHCIQueueHead) * MAX_HEADS);
            uhciDev.TransmitPool  = (UHCITransmitDescriptor *)Heap.AlignedAlloc(0x1000, sizeof(UHCITransmitDescriptor) * MAX_TRANSMIT);
            Memory.Memclear(uhciDev.QueueHeadPool, sizeof(UHCIQueueHead) * MAX_HEADS);
            Memory.Memclear(uhciDev.TransmitPool, sizeof(UHCITransmitDescriptor) * MAX_TRANSMIT);

            UHCIQueueHead *head = GetQueueHead(uhciDev);

            head->Head    = TD_POINTER_TERMINATE;
            head->Element = TD_POINTER_TERMINATE;

            uhciDev.FirstHead = head;


            for (int i = 0; i < 1024; i++)
            {
                uhciDev.FrameList[i] = TD_POINTER_QH | (int)Paging.GetPhysicalFromVirtual(head);
            }


            PortIO.Out16((ushort)(uhciDev.IOBase + REG_LEGSUP), 0x8f00);

            /**
             * Initalize framelist
             */
            PortIO.Out16((ushort)(uhciDev.IOBase + REG_FRNUM), 0);
            PortIO.Out32((ushort)(uhciDev.IOBase + REG_FRBASEADD), (uint)Paging.GetPhysicalFromVirtual(uhciDev.FrameList));
            PortIO.Out8(((ushort)(uhciDev.IOBase + REG_SOFMOD)), 0x40); // Ensure default value of 64 (aka cycle time of 12000)

            /**
             * We are going to poll!
             */
            PortIO.Out16((ushort)(uhciDev.IOBase + REG_USBINTR), 0x00);

            /**
             * Clear any pending statusses
             */
            PortIO.Out16((ushort)(uhciDev.IOBase + REG_USBSTS), 0xFFFF);

            /**
             * Enable device
             */
            PortIO.Out16((ushort)(uhciDev.IOBase + REG_USBCMD), USBCMD_RS);

            probe(uhciDev);

            Sharpen.USB.USB.RegisterController(uhciDev);
        }