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; } }
private static void WaitForWriteReady() { while ((PortIO.In8((ushort)(Port.Com1 + (ushort)Cmd.COM_ModemStatus)) & 0x20) == 0x0) { ; } }
/// <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!!"); } } }
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"); }
/// <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)); } }
/// <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)); } }
/// <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); }
/// <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)); }
/// <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); }
private void Wait() { // reading status byte takes 100ns PortIO.In8(StatusReg); PortIO.In8(StatusReg); PortIO.In8(StatusReg); PortIO.In8(StatusReg); }
/// <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)); }
/// <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(); } }
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); } }
/// <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); }
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); }
/// <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) { ; } }
/// <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"); }
/// <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) { ; } }
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); }
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"); } } }
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)); }
/// <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); }
private static void HandleIRQ(ref IRQContext context) { uint xScanCode = PortIO.In8(COMMAND); }
/// <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); }
/// <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); }
private static byte Read() { Wait(false); return(PortIO.In8(MOUSE_PORT)); }
/// <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); }