예제 #1
0
        private static void Wait(bool type)
        {
            int timeout = 100000;

            if (!type)
            {
                while (--timeout > 0)
                {
                    if ((PortIO.In8(MOUSE_STATUS) & MOUSE_BBIT) != 0)
                    {
                        return;
                    }
                }
                Debug.Write("[mouse]: TIMEOUT\n");
                return;
            }
            else
            {
                while (--timeout > 0)
                {
                    if ((PortIO.In8(MOUSE_STATUS) & MOUSE_ABIT) == 0)
                    {
                        return;
                    }
                }
                Debug.Write("[mouse]: TIMEOUT\n");
                return;
            }
        }
예제 #2
0
 private static void WaitForWriteReady()
 {
     while ((PortIO.In8((ushort)(Port.Com1 + (ushort)Cmd.COM_ModemStatus)) & 0x20) == 0x0)
     {
         ;
     }
 }
예제 #3
0
        /// <summary>
        /// Wait for drive to be finished
        /// </summary>
        /// <param name="port">Port IO base</param>
        private static void poll(uint port)
        {
            wait400ns(port);

            byte status;

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

            while ((status & ATA_STATUS_DRQ) == 0)
            {
                status = PortIO.In8((ushort)(port + ATA_REG_STATUS));

                if ((status & ATA_STATUS_DF) > 0)
                {
                    Panic.DoPanic("Device fault!");
                }

                if ((status & ATA_STATUS_ERR) > 0)
                {
                    Panic.DoPanic("ERR IN ATA!!");
                }
            }
        }
예제 #4
0
        internal static void Setup()
        {
            Debug.Write("PS/2 Mouse Controller Setup\n");
            MouseCycle   = 0;
            MouseData    = new byte[4];
            MouseData[0] = MOUSE_MAGIC;
            MousePipe    = new Pipe(4, 1024);
            IDT.RegisterInterrupt(HandleIRQ, 0x2C);

            Wait(true);
            PortIO.Out8(MOUSE_STATUS, 0xA8);
            Wait(true);
            PortIO.Out8(MOUSE_STATUS, 0x20);
            Wait(false);

            byte status = (byte)(PortIO.In8(MOUSE_PORT) | 2);

            Wait(true);
            PortIO.Out8(MOUSE_STATUS, 0x60);
            Wait(true);
            PortIO.Out8(MOUSE_PORT, status);
            Write(0xF6);
            Read();
            Write(0xF4);
            Read();

            Debug.Write("Mouse Done\n");
        }
예제 #5
0
 /// <summary>
 /// Read mac address from device
 /// </summary>
 private static void readMac()
 {
     for (int i = 0; i < 6; i++)
     {
         m_mac[i] = PortIO.In8((ushort)(m_io_base + i));
     }
 }
예제 #6
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));
            }
        }
예제 #7
0
        /// <summary>
        /// Update link status
        /// </summary>
        private static void updateLinkStatus()
        {
            byte b = PortIO.In8((ushort)(m_io_base + REG_MS));

            m_linkFail = ((b & MS_LINKB) == 0);
            m_100mbit  = ((b & MS_SPEED_10) == 0);
        }
예제 #8
0
 /// <summary>
 /// Waits 400 ns on an ATA device
 /// </summary>
 /// <param name="port">The base IO port</param>
 private static void wait400ns(uint port)
 {
     PortIO.In8((ushort)(port + ATA_REG_ALTSTATUS));
     PortIO.In8((ushort)(port + ATA_REG_ALTSTATUS));
     PortIO.In8((ushort)(port + ATA_REG_ALTSTATUS));
     PortIO.In8((ushort)(port + ATA_REG_ALTSTATUS));
 }
예제 #9
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);
        }
예제 #10
0
파일: IDE.cs 프로젝트: fossabot/AtomOS-1
 private void Wait()
 {
     // reading status byte takes 100ns
     PortIO.In8(StatusReg);
     PortIO.In8(StatusReg);
     PortIO.In8(StatusReg);
     PortIO.In8(StatusReg);
 }
예제 #11
0
        /// <summary>
        /// Read from serial port
        /// </summary>
        /// <param name="port">The serial port</param>
        /// <returns>Read data</returns>
        private static byte read(ushort port)
        {
            while (!hasReceived(port))
            {
                CPU.HLT();
            }

            return(PortIO.In8(port));
        }
예제 #12
0
        /// <summary>
        /// Software reset device
        /// </summary>
        private static void softwareReset()
        {
            PortIO.Out8((ushort)(m_io_base + REG_CMD), CMD_RST);

            /**
             * Wait for device to reset, bit will be set down on reset
             */
            while ((PortIO.In8((ushort)(m_io_base + REG_CMD)) & CMD_RST) > 0)
            {
                CPU.HLT();
            }
        }
예제 #13
0
        private static void HandleIRQ(ref IRQContext context)
        {
            int status = PortIO.In8(MOUSE_STATUS);

            while ((status & MOUSE_BBIT) != 0)
            {
                if ((status & MOUSE_F_BIT) != 0)
                {
                    byte input = PortIO.In8(MOUSE_PORT);
                    switch (MouseCycle)
                    {
                    case 0:
                    {
                        MouseData[1] = input;
                        if ((input & MOUSE_V_BIT) != 0)
                        {
                            MouseCycle = 1;
                        }
                    }
                    break;

                    case 1:
                    {
                        MouseData[2] = input;
                        MouseCycle   = 2;
                    }
                    break;

                    case 2:
                    {
                        MouseData[3] = input;
                        MouseCycle   = 0;

                        /*
                         * http://wiki.osdev.org/Mouse_Input
                         * The top two bits of the first byte (values 0x80 and 0x40) supposedly show Y and X overflows,
                         * respectively. They are not useful. If they are set, you should probably just discard the entire packet.
                         */
                        if ((MouseData[1] & 0xC0) != 0)         // X-Y (0x40 & 0x80) Overflow
                        {
                            break;
                        }

                        // Send packet to kernel:= { MAGIC, btn, X-Pos, Y-Pos }
                        // Send package and seek the read pointer if necessary
                        MousePipe.Write(MouseData, false);
                    }
                    break;
                    }
                }
                status = PortIO.In8(MOUSE_STATUS);
            }
        }
예제 #14
0
        /// <summary>
        /// Keyboard IRQ handler
        /// </summary>
        /// <returns></returns>
        private static unsafe bool handler()
        {
            byte scancode = PortIO.In8(0x60);

            // Key up?
            if ((scancode & 0x80) > 0)
            {
                if (scancode == 0xAA)
                {
                    m_shift &= 0x02;
                }
                else if (scancode == 0xB6)
                {
                    m_shift &= 0x01;
                }
            }
            else
            {
                if (scancode == 0x3A)
                {
                    if (m_capslock > 0)
                    {
                        m_capslock = 0;
                        m_leds     = 0;
                    }
                    else
                    {
                        m_capslock = 1;
                        m_leds     = 4;
                    }
                    updateLED();
                }
                else if (scancode == 0x2A)
                {
                    m_shift |= 0x01;
                }
                else if (scancode == 0x36)
                {
                    m_shift |= 0x02;
                }
                else
                {
                    readchar = transformKey(scancode);

                    m_fifo.WriteByte((byte)readchar);

                    readingchar = 0;
                }
            }

            return(true);
        }
예제 #15
0
        private static void SetFrequency(int Hz)
        {
            int divisor = 1193180 / Hz;

            PortIO.Out8(0x43, 0x36);                            /* Set our command byte 0x36 */
            PortIO.Out8(0x40, (byte)(divisor & 0xFF));          /* Set low byte of divisor */
            PortIO.Out8(0x40, (byte)(divisor >> 8));            /* Set high byte of divisor */

            /* Enable Timer IRQ (Clear mask) */
            byte value = (byte)(PortIO.In8(0x21) & 0xFE);

            PortIO.Out8(0x21, value);
        }
예제 #16
0
 /// <summary>
 /// Updates the LED
 /// </summary>
 private static void updateLED()
 {
     PortIO.Out8(0x60, 0xED);
     while ((PortIO.In8(0x64) & 2) > 0)
     {
         ;
     }
     PortIO.Out8(0x60, m_leds);
     while ((PortIO.In8(0x64) & 2) > 0)
     {
         ;
     }
 }
예제 #17
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");
        }
예제 #18
0
        /// <summary>
        /// Sleeps
        /// </summary>
        /// <param name="sleepDivisor">The sleep divisor</param>
        public static void Sleep(uint sleepDivisor)
        {
            // Write sleep divisor
            PortIO.Out8(PIT_DATA_2, (byte)(sleepDivisor & 0xFF));
            PortIO.Out8(PIT_DATA_2, (byte)(sleepDivisor >> 8));

            // Reset PIT counter and start
            byte controlByte = PortIO.In8(0x61);

            PortIO.Out8(0x61, (byte)(controlByte & ~1));
            PortIO.Out8(0x61, (byte)(controlByte | 1));

            // Wait until the PIT counter reaches zero
            while ((PortIO.In8(0x61) & 0x20) == 0)
            {
                ;
            }
        }
예제 #19
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);
        }
예제 #20
0
파일: IDE.cs 프로젝트: fossabot/AtomOS-1
        private void Poll(bool AdvancedCheck)
        {
            // (I) Delay 400 nanosecond for BSY to be set:
            Wait();

            // (II) Wait for BSY to be cleared:
            // -------------------------------------------------
            while (((Status)PortIO.In8(StatusReg) & Status.ATA_SR_BSY) != 0)
            {
                ; // Wait for BSY to be zero.
            }
            if (AdvancedCheck)
            {
                var xState = (Status)PortIO.In8(StatusReg);

                // (III) Check For Errors:
                // -------------------------------------------------
                if ((xState & Status.ATA_SR_ERR) != 0)
                {
                    throw new Exception("ATA Error");
                }

                // (IV) Check If Device fault:
                // -------------------------------------------------
                if ((xState & Status.ATA_SR_DF) != 0)
                {
                    throw new Exception("ATA Device Fault");
                }

                // (V) Check DRQ:
                // -------------------------------------------------
                // BSY = 0; DF = 0; ERR = 0 so we should check for DRQ now.
                if ((xState & Status.ATA_SR_DRQ) == 0)
                {
                    throw new Exception("ATA DRQ should be set");
                }
            }
        }
예제 #21
0
        public const uint CMOS_RTC_HOURS_PM = (1 << 7); // Bit 7 is set on read hours value if it's in pm

        /// <summary>
        /// Gets data from a CMOS register
        /// </summary>
        /// <param name="reg">The register to read the data from</param>
        /// <returns>The data</returns>
        public static byte GetData(byte reg)
        {
            PortIO.Out8(CMOS_CMD, reg);
            return(PortIO.In8(CMOS_DATA));
        }
예제 #22
0
 /// <summary>
 /// Byte received on port?
 /// </summary>
 /// <param name="port">The serialport</param>
 /// <returns>If there are bytes received</returns>
 private static bool hasReceived(int port)
 {
     return((PortIO.In8((ushort)(port + 0x05)) & 1) > 0);
 }
예제 #23
0
파일: Keyboard.cs 프로젝트: vdt/AtomOS
 private static void HandleIRQ(ref IRQContext context)
 {
     uint xScanCode = PortIO.In8(COMMAND);
 }
예제 #24
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);
        }
예제 #25
0
 /// <summary>
 /// Is the transmit empty?
 /// </summary>
 /// <param name="port">The serialport</param>
 /// <returns>If the transmit is empty</returns>
 private static bool isTransmitEmpty(int port)
 {
     return((PortIO.In8((ushort)(port + 0x05)) & 0x20) == 0);
 }
예제 #26
0
 private static byte Read()
 {
     Wait(false);
     return(PortIO.In8(MOUSE_PORT));
 }
예제 #27
0
파일: IDE.cs 프로젝트: fossabot/AtomOS-1
        /// <summary>
        /// This method discover the current ATA device and try to read all its configurations
        /// </summary>
        private void Discover()
        {
            mDevice     = Device.IDE_None;
            mBufferSize = 0;

            Status xStatus;
            bool   Error = false;

            // Select Drive
            SelectDrive();

            // Send Identify command
            PortIO.Out8(CommandReg, (byte)Cmd.ATA_CMD_IDENTIFY);
            Wait();

            if (PortIO.In8(StatusReg) == 0)
            {
                return; // No Device
            }
            while (true)
            {
                xStatus = (Status)PortIO.In8(StatusReg);
                if ((xStatus & Status.ATA_SR_ERR) != 0)
                {
                    Error = true; // If Err, Device is not ATA.
                    break;
                }

                if (((xStatus & Status.ATA_SR_BSY) == 0) && ((xStatus & Status.ATA_SR_DRQ) != 0))
                {
                    break; // Everything is fine
                }
                Wait();
            }

            mDevice     = Device.IDE_ATA;
            mBufferSize = 512;

            // (IV) Probe for ATAPI Devices:
            if (Error)
            {
                ushort xTypeID = (ushort)(PortIO.In8(LBA2) << 8 | PortIO.In8(LBA1));
                if (xTypeID == 0xEB14 || xTypeID == 0x9669)
                {
                    mDevice       = Device.IDE_ATAPI;
                    mBufferSize   = 2048;
                    mATAPI_Packet = new byte[12];
                }
                else
                {
                    mDevice     = Device.IDE_None;
                    mBufferSize = 0;
                    return;
                }

                // Send Identify packet command
                PortIO.Out8(CommandReg, (byte)Cmd.ATA_CMD_IDENTIFY_PACKET);
                Wait();
            }

            var xBuff = new ushort[256];

            PortIO.Read16(DataReg, xBuff);

            // ATA/ATAPI COnfig
            mIsRemovable = (xBuff[(int)Identify.ATA_IDENT_DEVICETYPE] & (1 << 7)) > 0;

            // CHS configurations
            mCylinder        = xBuff.ToUInt32((int)Identify.ATA_IDENT_CYLINDERS);
            mHeads           = xBuff.ToUInt32((int)Identify.ATA_IDENT_HEADS);
            mSectorsPerTrack = xBuff.ToUInt32((int)Identify.ATA_IDENT_SECTORS);
            mCommandSet      = xBuff.ToUInt32((int)Identify.ATA_IDENT_COMMANDSETS);

            ushort xFieldValid = xBuff[(int)Identify.ATA_IDENT_FIELDVALID];

            // 1st bit determine weather it support LBA or not
            mLBASupport = (bool)((xFieldValid & 1) == 1);

            if ((mCommandSet & (1 << 26)) != 0)
            {
                // Device uses 48-Bit Addressing:
                throw new Exception("48bit addresssing not supported");
            }
            //mSize = xBuff.ToUInt48((int)Identify.ATA_IDENT_MAX_LBA_EXT);
            else
            {
                // Device uses CHS or 28-bit Addressing:
                mSize = xBuff.ToUInt32((int)Identify.ATA_IDENT_MAX_LBA);
            }

            // Read Model, Firmware, SerialNo.
            mModel    = xBuff.GetString((int)Identify.ATA_IDENT_MODEL, 40);
            mSerialNo = xBuff.GetString((int)Identify.ATA_IDENT_SERIAL, 20);
        }