/// <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> /// 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> /// 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"); }
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); }
/// <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> /// 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); } }
/// <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); }
/// <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> /// Set interrupt mask /// </summary> private static void setInterruptMask(ushort value) { PortIO.Out16((ushort)(m_io_base + REG_IMR), value); }
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); }