/* * private bool Access_Disk(UInt32 SectorNo, uint SectorCount, byte* xData, bool IsReading) * { * if (mDevice == Device.IDE_ATAPI) * { * if (IsReading) * { * if (SectorCount != 1)// Only 1 sector we can read at a time * return false; * * // Lock up device * //Monitor.AcquireLock(this); * * // SCSI Packet Command * mATAPI_Packet[0] = (byte)Cmd.ATAPI_CMD_READ; * mATAPI_Packet[1] = 0x00; * mATAPI_Packet[2] = (byte)((SectorNo >> 24) & 0xFF); * mATAPI_Packet[3] = (byte)((SectorNo >> 16) & 0xFF); * mATAPI_Packet[4] = (byte)((SectorNo >> 8) & 0xFF); * mATAPI_Packet[5] = (byte)((SectorNo >> 0) & 0xFF); * mATAPI_Packet[6] = 0x00; * mATAPI_Packet[7] = 0x00; * mATAPI_Packet[8] = 0x00; * mATAPI_Packet[9] = (byte)(SectorCount & 0xFF); * mATAPI_Packet[10] = 0x00; * mATAPI_Packet[11] = 0x00; * * // Enable IRQ * IRQInvoked = false; * PortIO.Out8(ControlReg, 0x0); * * SelectDrive(); * * PortIO.Out8(FeatureReg, 0x0);// Tell controller that we are going to use PIO mode * * // Tell constroller the size of each buffer * PortIO.Out8(LBA1, (byte)((mBufferSize) & 0xFF));// Lower Byte of Sector Size. ATA_LBA_MID_PORT * PortIO.Out8(LBA2, (byte)((mBufferSize >> 8) & 0xFF));// Upper Byte of Sector Size. ATA_LBA_HI_PORT * * // Send Packet command * Send_SCSI_Package(); * * // Actual size that is to transferred * int size = (PortIO.In8(LBA2) << 8 | PortIO.In8(LBA1)); * * // Read the data * PortIO.Read16(DataReg, xData, size); * * WaitIRQ(); * while (((Status)PortIO.In8(StatusReg) & (Status.ATA_SR_BSY | Status.ATA_SR_DRQ)) != 0) ; * * // UnLock up device * //Monitor.ReleaseLock(this); * * return true; * } * return false; * } * else if (mDevice == Device.IDE_ATA) * { * // Lock up device * //Monitor.AcquireLock(this); * * // Disable IRQ * IRQInvoked = false; * PortIO.Out8(ControlReg, 0x2); * * ushort lba_mode, cyl; * byte head, sect; * byte[] lba_io = new byte[6]; * * // (I) Select one from LBA28, LBA48 or CHS; * if (SectorNo >= 0x10000000) * { * // LBA48: * lba_mode = 2; * lba_io[0] = (byte)((SectorNo & 0x000000FF) >> 0); * lba_io[1] = (byte)((SectorNo & 0x0000FF00) >> 8); * lba_io[2] = (byte)((SectorNo & 0x00FF0000) >> 16); * lba_io[3] = (byte)((SectorNo & 0xFF000000) >> 24); * lba_io[4] = 0; // LBA28 is integer, so 32-bits are enough to access 2TB. * lba_io[5] = 0; // LBA28 is integer, so 32-bits are enough to access 2TB. * head = 0; // Lower 4-bits of HDDEVSEL are not used here. * } * else if ((mCommandSet & (1 << 26)) != 0) * { * // LBA28: * lba_mode = 1; * lba_io[0] = (byte)((SectorNo & 0x00000FF) >> 0); * lba_io[1] = (byte)((SectorNo & 0x000FF00) >> 8); * lba_io[2] = (byte)((SectorNo & 0x0FF0000) >> 16); * lba_io[3] = 0; // These Registers are not used here. * lba_io[4] = 0; // These Registers are not used here. * lba_io[5] = 0; // These Registers are not used here. * head = (byte)((SectorNo & 0xF000000) >> 24); * } * else * { * // CHS: * lba_mode = 0; * sect = (byte)((SectorNo % 63) + 1); * cyl = (ushort)((SectorNo + 1 - sect) / (16 * 63)); * lba_io[0] = (byte)(sect & 0xFF); * lba_io[1] = (byte)((cyl >> 0) & 0xFF); * lba_io[2] = (byte)((cyl >> 8) & 0xFF); * lba_io[3] = 0; * lba_io[4] = 0; * lba_io[5] = 0; * head = (byte)((SectorNo + 1 - sect) % (16 * 63) / (63)); // Head number is written to HDDEVSEL lower 4-bits. * } * * while (((Status)PortIO.In8(StatusReg) & Status.ATA_SR_BSY) != 0) ; * * // (IV) Select Drive from the controller; * if (lba_mode == 0) * SelectDrive(head, false); * else * SelectDrive(head, true); * * // (V) Write Parameters; * if (lba_mode == 2) * { * Debug.Write("IDE: LBA_MODE=2 YET TO IMPLEMENT\n"); * throw new Exception("Yet to implement"); * } * PortIO.Out8(SectorCountReg, (byte)(SectorCount & 0xFF)); * PortIO.Out8(LBA0, lba_io[0]); * PortIO.Out8(LBA1, lba_io[1]); * PortIO.Out8(LBA2, lba_io[2]); * * // Free up this memory * Heap.Free(lba_io); * * // We are not using DMA so don't care about that * byte cmd = 0; * if (lba_mode == 0 && IsReading) cmd = (byte)Cmd.ATA_CMD_READ_PIO; * else if (lba_mode == 1 && IsReading) cmd = (byte)Cmd.ATA_CMD_READ_PIO; * else if (lba_mode == 2 && IsReading) cmd = (byte)Cmd.ATA_CMD_READ_PIO_EXT; * else if (lba_mode == 0 && !IsReading) cmd = (byte)Cmd.ATA_CMD_WRITE_PIO; * else if (lba_mode == 1 && !IsReading) cmd = (byte)Cmd.ATA_CMD_WRITE_PIO; * else if (lba_mode == 2 && !IsReading) cmd = (byte)Cmd.ATA_CMD_WRITE_PIO_EXT; * * PortIO.Out8(CommandReg, cmd); * * if (IsReading) * { * // PIO Read. * Poll(true);// Polling, set error and exit if there is. * PortIO.Read16(DataReg, xData); * } * else * { * // PIO Write. * Poll(false);// Just Poll we don't want any error * PortIO.Write16(DataReg, xData); * switch (lba_mode) * { * case 0: * case 1: * PortIO.Out8(CommandReg, (byte)Cmd.ATA_CMD_CACHE_FLUSH); * break; * case 2: * PortIO.Out8(CommandReg, (byte)Cmd.ATA_CMD_CACHE_FLUSH_EXT); * break; * }; * Poll(false); * } * * // UnLock up device * //Monitor.ReleaseLock(this); * return true; * } * return false; * }*/ internal override bool Eject() { if (mDevice == Device.IDE_ATAPI) { // SCSI Packet Command mATAPI_Packet[0] = (byte)Cmd.ATAPI_CMD_EJECT; mATAPI_Packet[1] = 0x00; mATAPI_Packet[2] = 0x00; mATAPI_Packet[3] = 0x00; mATAPI_Packet[4] = 0x02; mATAPI_Packet[5] = 0x00; mATAPI_Packet[6] = 0x00; mATAPI_Packet[7] = 0x00; mATAPI_Packet[8] = 0x00; mATAPI_Packet[9] = 0x00; mATAPI_Packet[10] = 0x00; mATAPI_Packet[11] = 0x00; // Enable IRQ; Currently IRQ is not working...so we ignore it but very important IRQInvoked = false; PortIO.Out8(ControlReg, 0x0); SelectDrive(); Send_SCSI_Package(); return(true); } return(false); }
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"); }
private static void Remap(byte masterStart, byte masterMask, byte slaveStart, byte slaveMask) { PortIO.Out8(PIC1_Command, ICW1_Initialization + ICW1_ICW4); PortIO.Wait(); PortIO.Out8(PIC2_Command, ICW1_Initialization + ICW1_ICW4); PortIO.Wait(); PortIO.Out8(PIC1_Data, masterStart); PortIO.Wait(); PortIO.Out8(PIC2_Data, slaveStart); PortIO.Wait(); PortIO.Out8(PIC1_Data, 4); PortIO.Wait(); PortIO.Out8(PIC2_Data, 2); PortIO.Wait(); // set modes: PortIO.Out8(PIC1_Data, ICW4_8086); PortIO.Wait(); PortIO.Out8(PIC2_Data, ICW4_8086); PortIO.Wait(); // set masks: PortIO.Out8(PIC1_Data, masterMask); PortIO.Wait(); //PortIO.Out8(PIC2_Data, slaveMask); //PortIO.Wait(); }
private static void Write(byte data) { Wait(true); PortIO.Out8(MOUSE_STATUS, MOUSE_WRITE); Wait(true); PortIO.Out8(MOUSE_PORT, data); }
/// <summary> /// Init device /// </summary> /// <param name="num"></param> private static void initDevice(int num) { if (comports[num].Address == 0) { return; } ushort port = comports[num].Address; PortIO.Out8((ushort)(port + 1), 0x00); PortIO.Out8((ushort)(port + 3), 0x80); PortIO.Out8((ushort)(port + 0), 0x01); PortIO.Out8((ushort)(port + 1), 0x00); PortIO.Out8((ushort)(port + 3), 0x03); PortIO.Out8((ushort)(port + 2), 0xC7); PortIO.Out8((ushort)(port + 4), 0x0B); PortIO.Out8((ushort)(port + 1), 0x01); comports[num].Buffer = new Fifo(256, true); Node node = new Node(); node.Flags = NodeFlags.FILE; node.Write = writeImpl; node.Read = readImpl; node.GetSize = getSizeImpl; node.Cookie = new IDCookie(num); RootPoint dev = new RootPoint(comports[num].Name, node); VFS.MountPointDevFS.AddEntry(dev); }
/// <summary> /// Select IDE drive /// </summary> /// <param name="channel">Channel slave of master?</param> /// <param name="drive">Drive slave of master?</param> private static void selectDrive(byte channel, byte drive) { ushort io = (channel == ATA_PRIMARY) ? ATA_PRIMARY_IO : ATA_SECONDARY_IO; byte data = (drive == ATA_MASTER) ? (byte)0xA0 : (byte)0xB0; PortIO.Out8((ushort)(io + ATA_REG_DRIVE), data); }
/// <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> /// Prepares the PIT to sleep a couple of microseconds /// </summary> /// <param name="us">The microseconds</param> /// <returns>The sleep divisor</returns> public static uint PrepareSleep(uint us) { // Initialize PIT PortIO.Out8(PIT_CMD, PIT_DATA_2 | PIT_MODE_IOTC | PIT_ACCESS_LOHIBYTE); uint sleepDivisor = PIT_FREQUENCY / (1000000 / us); return(sleepDivisor); }
/// <summary> /// Moves the VGA cursor /// </summary> private static void MoveCursor() { int index = Y * 80 + X; PortIO.Out8(0x3D4, 14); PortIO.Out8(0x3D5, (byte)(index >> 8)); PortIO.Out8(0x3D4, 15); PortIO.Out8(0x3D5, (byte)(index & 0xFF)); }
internal static void EndOfInterrupt(int irq) { if (irq >= 40) // or untranslated IRQ >= 8 { PortIO.Out8(PIC2_Command, EOI); } PortIO.Out8(PIC1_Command, EOI); }
/// <summary> /// Write to serial port /// </summary> /// <param name="d">The data</param> /// <param name="port">The port</param> public static void write(byte d, ushort port) { while (isTransmitEmpty(port)) { CPU.HLT(); } PortIO.Out8(port, d); }
/// <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> /// 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 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"); }
internal static void Init() { var PORT = Port.Com1; PortIO.Out8((ushort)(PORT + (ushort)Cmd.COM_Interrupt), 0x00); // Disable all interrupts PortIO.Out8((ushort)(PORT + (ushort)Cmd.COM_ModemControl), 0x80); // Enable DLAB (set baud rate divisor) PortIO.Out8((ushort)(PORT + (ushort)Cmd.COM_Data), 0x03); // Set divisor to 3 (lo byte) 38400 baud PortIO.Out8((ushort)(PORT + (ushort)Cmd.COM_Interrupt), 0x00); // (hi byte) PortIO.Out8((ushort)(PORT + (ushort)Cmd.COM_ModemControl), 0x03); // 8 bits, no parity, one stop bit PortIO.Out8((ushort)(PORT + (ushort)Cmd.COM_LineControl), 0xC7); // Enable FIFO, clear them, with 14-byte threshold PortIO.Out8((ushort)(PORT + (ushort)Cmd.COM_LineStatus), 0x0B); // IRQs enabled, RTS/DSR set PortIO.Out8((ushort)(PORT + (ushort)Cmd.COM_Interrupt), 0x0F); Write("Debugger Initalized\n"); }
private void Send_SCSI_Package() { // Tell Controller that we are sending package PortIO.Out8(CommandReg, (byte)Cmd.ATA_CMD_PACKET); // Wait till device get ready Poll(true); // Send SCSI-Packet command to controller PortIO.Write16(DataReg, mATAPI_Packet); // IRQ WaitIRQ(); // Poll and check for error Poll(false); }
/// <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) { ; } }
internal IDE(bool IsPrimary, bool IsMaster = true) { UInt16 xBAR0 = (UInt16)(IsPrimary ? 0x01F0 : 0x0170); UInt16 xBAR1 = (UInt16)(IsPrimary ? 0x03F6 : 0x0376); mChannel = IsPrimary ? Channel.PRIMARY : Channel.SECONDARY; mType = IsMaster ? Type.MASTER : Type.SLAVE; DataReg = (UInt16)(xBAR0 + (byte)Register.ATA_REG_DATA); FeatureReg = (UInt16)(xBAR0 + (byte)Register.ATA_REG_FEATURES); SectorCountReg = (UInt16)(xBAR0 + (byte)Register.ATA_REG_SECCOUNT0); CommandReg = (UInt16)(xBAR0 + (byte)Register.ATA_REG_COMMAND); StatusReg = (UInt16)(xBAR0 + (byte)Register.ATA_REG_STATUS); AltStatusReg = (UInt16)(xBAR1 + (byte)Register.ATA_REG_ALTSTATUS); ControlReg = (UInt16)(xBAR1 + (byte)Register.ATA_REG_CONTROL); LBA0 = (UInt16)(xBAR0 + (byte)Register.ATA_REG_LBA0); LBA1 = (UInt16)(xBAR0 + (byte)Register.ATA_REG_LBA1); LBA2 = (UInt16)(xBAR0 + (byte)Register.ATA_REG_LBA2); DeviceSelect = (UInt16)(xBAR0 + (byte)Register.ATA_REG_HDDEVSEL); // Disable IRQ PortIO.Out8(ControlReg, 0x2); // Discover what we have =P Discover(); if (mDevice != Device.IDE_None) { IRQInvoked = false; // Register Interrupt Handler :-) IDT.RegisterInterrupt( delegate(ref IRQContext xContext) { IRQInvoked = true; }, (uint)(IsPrimary ? 0x2E : 0x2F)); } }
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> /// Remaps the IRQs /// </summary> public static void Remap() { // Initialize PortIO.Out8(MASTER_PIC_CMD, PIC_INIT); PortIO.Out8(SLAVE_PIC_CMD, PIC_INIT); // Offsets PortIO.Out8(MASTER_PIC_DATA, IRQ.MASTER_OFFSET); PortIO.Out8(SLAVE_PIC_DATA, IRQ.SLAVE_OFFSET); // Tell master there's a slave PIC at IRQ2 PortIO.Out8(MASTER_PIC_DATA, 4); // Tell slave its cascade identity PortIO.Out8(SLAVE_PIC_DATA, PIC_CASCADE); // 8086 mode PortIO.Out8(MASTER_PIC_DATA, PIC_8086); PortIO.Out8(SLAVE_PIC_DATA, PIC_8086); // Mask PIC IRQs because we're going to use the APIC PortIO.Out8(MASTER_PIC_DATA, 0xFF); PortIO.Out8(SLAVE_PIC_DATA, 0xFF); }
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); }
/// <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); }
/// <summary> /// Initialization handler /// </summary> /// <param name="dev">This PCI device</param> private static unsafe void initHandler(PciDevice dev) { m_io_base = (ushort)(dev.BAR0.Address); /** * Check if I/O bar */ if ((dev.BAR0.flags & Pci.BAR_IO) == 0) { Console.WriteLine("[RTL8139] RTL8139 should be an I/O bar, not a memory bar!"); return; } /** * Set interrupt */ Pci.SetInterruptHandler(dev, handler); /** * Enable bus mastering */ Pci.EnableBusMastering(dev); /** * Enable device */ PortIO.Out8((ushort)(m_io_base + REG_CONF1), 0); /** * Do a software reset */ softwareReset(); /** * Initalize and allocate buffers */ initializeBuffers(); /** * Setup interrupts */ setInterruptMask(IMR_TOK | IMR_TER | IMR_ROK | IMR_RER); /** * Initalize transmit */ txInit(); /** * Initalize receive */ rxInit(); /** * Read mac address */ readMac(); /** * Update link status */ updateLinkStatus(); /** * Enable receiving and transmitting! */ PortIO.Out8((ushort)(m_io_base + REG_CMD), CMD_TE | CMD_RE); Console.WriteLine("[RTL8139] Initialized"); /** * Register device as the main network device */ Network.NetDevice netDev = new Network.NetDevice(); netDev.ID = dev.Device; netDev.Transmit = Transmit; netDev.GetMac = GetMac; Network.Set(netDev); }
/// <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); }
public static void Write(byte a) { WaitForWriteReady(); PortIO.Out8((ushort)Port.Com1, a); }
private void SelectDrive() { PortIO.Out8(DeviceSelect, (byte)((byte)mType << 4)); Wait(); }
private void SelectDrive(byte head, bool lba) { PortIO.Out8(DeviceSelect, (byte)((lba ? 0xE0 : 0xA0) | ((byte)mType << 4) | head)); // Drive & LBA || Drive & CHS Wait(); }