/// <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); }
/// <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); }
/// <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); }
/// <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; } } }
/// <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); }
/// <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); } } }
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 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); }
/// <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); }
/// <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); }