/// <summary> /// Initalize RXs /// </summary> private static unsafe void rxInit() { /** * Allocate receive descriptors */ m_rx_descs = (RX_DESC *)Heap.AlignedAlloc(16, NUM_RX_DESCRIPTORS * sizeof(RX_DESC)); m_rx_buffers = new byte *[NUM_RX_DESCRIPTORS]; for (int i = 0; i < NUM_RX_DESCRIPTORS; i++) { m_rx_buffers[i] = (byte *)Heap.AlignedAlloc(16, 8192); m_rx_descs[i].Address = (uint)(Paging.GetPhysicalFromVirtual(m_rx_buffers[i])); m_rx_descs[i].Status = 0; } /** * Set rx address to device */ *(uint *)(m_register_base + REG_RDBAL) = (uint)Paging.GetPhysicalFromVirtual(m_rx_descs); *(uint *)(m_register_base + REG_RDBAH) = 0; /** * Setup total length */ *(uint *)(m_register_base + REG_RDLEN) = NUM_RX_DESCRIPTORS * (uint)sizeof(RX_DESC); *(uint *)(m_register_base + REG_RDH) = 0; *(uint *)(m_register_base + REG_RDT) = NUM_RX_DESCRIPTORS - 1; /** * Setup read control register */ *(uint *)(m_register_base + REG_RCTL) = REG_RCTL_BSEX | REG_RCTL_BSECRC | REG_RCT_BAM | REG_RCT_LPE | (1 << 1) | REG_RCT_SBP | (2 << 16); }
/// <summary> /// Creates a new page directory using only physical memory (used in Init) /// </summary> /// <param name="flags">The flags</param> /// <returns>The page directory</returns> public static PageDirectory *CreateNewDirectoryPhysically(PageFlags flags) { // Allocate a new block of physical memory to store our physical page in PageDirectory *directory = (PageDirectory *)Heap.AlignedAlloc(0x1000, sizeof(PageDirectory)); directory->PhysicalDirectory = directory; if (directory == null) { Panic.DoPanic("directory == null"); } // Allocate the tables for (int i = 0; i < 1024; i++) { PageTable *table = (PageTable *)PhysicalMemoryManager.Alloc(); if (table == null) { Panic.DoPanic("table == null"); } Memory.Memclear(table, sizeof(PageTable)); // Note: At this point, virtual address == physical address due to identity mapping directory->PhysicalTables[i] = (int)table | (int)flags; directory->VirtualTables[i] = (int)table; } return(directory); }
/// <summary> /// Initialize buffers /// </summary> private static unsafe void initializeBuffers() { m_buffer = (byte *)Heap.AlignedAlloc(0x1000, 8192); m_transmits = new byte *[4]; for (int i = 0; i < 4; i++) { m_transmits[i] = (byte *)Heap.AlignedAlloc(0x1000, 1536); } m_mac = new byte[6]; }
/// <summary> /// Sets up the stacks /// </summary> private void createStacks() { int *stacks = (int *)Heap.AlignedAlloc(16, KernelStackSize + UserStackSize); m_stackStart = (int *)((int)stacks + KernelStackSize); m_stack = (int *)((int)m_stackStart + UserStackSize); m_kernelStackStart = stacks; m_kernelStack = (int *)((int)m_kernelStackStart + KernelStackSize); }
/// <summary> /// Clones a page directory and its tables /// </summary> /// <param name="source">The source page directory</param> /// <returns>The cloned page directory</returns> public static PageDirectory *CloneDirectory(PageDirectory *source) { // Note: sizeof(PageDirectory) is not neccesarily a page int pageDirSizeAligned = (int)AlignUp((uint)sizeof(PageDirectory)); // One block for the page directory and the page tables int allocated = (int)Heap.AlignedAlloc(0x1000, pageDirSizeAligned + 1024 * sizeof(PageTable)); if (allocated == 0) { Panic.DoPanic("Couldn't clone page directory because there is no memory left"); } PageDirectory *destination = (PageDirectory *)allocated; destination->PhysicalDirectory = (PageDirectory *)GetPhysicalFromVirtual((void *)allocated); for (int i = 0; i < 1024; i++) { int sourceTable = source->VirtualTables[i]; if (sourceTable == 0) { Panic.DoPanic("sourceTable == 0?!"); } // Get the pointer without the flags and the flags seperately PageTable *sourceTablePtr = (PageTable *)sourceTable; int flags = source->PhysicalTables[i] & 0xFFF; // Calculate addresses int addressOffset = pageDirSizeAligned + i * sizeof(PageTable); PageTable *newTable = (PageTable *)(allocated + addressOffset); int newTablePhysical = (int)GetPhysicalFromVirtual(newTable); // Copy table data and set pointers Memory.Memcpy(newTable, sourceTablePtr, sizeof(PageTable)); destination->PhysicalTables[i] = newTablePhysical | flags; destination->VirtualTables[i] = (int)newTable; } return(destination); }
/// <summary> /// Creates a new context /// </summary> /// <param name="eip">The initial instruction pointer</param> /// <param name="initialStackSize">Initial stack size</param> /// <param name="initialStack">Initial stack data</param> /// <param name="kernelContext">If this is a kernel context or not</param> public void CreateNewContext(void *eip, int initialStackSize, int[] initialStack, bool kernelContext) { createStacks(); // Copy initial stack for (int i = 0; i < initialStackSize; i++) { *--m_stack = initialStack[i]; } // Descriptors from the GDT int cs = (kernelContext ? KernelCS : UserspaceCS); int ds = (kernelContext ? KernelDS : UserspaceDS); // Continue with stacks m_stack = writeSchedulerStack(m_stack, m_stack, cs, ds, eip); // FPU context m_FPUContext = Heap.AlignedAlloc(16, 512); FPU.StoreContext(m_FPUContext); }
/// <summary> /// Initalize TX /// </summary> private static unsafe void txInit() { /** * Allocate transmit descriptors */ m_tx_descs = (TX_DESC *)Heap.AlignedAlloc(16, NUM_TX_DESCRIPTIORS * sizeof(TX_DESC)); m_tx_buffers = new byte *[NUM_TX_DESCRIPTIORS]; for (int i = 0; i < NUM_TX_DESCRIPTIORS; i++) { m_tx_buffers[i] = (byte *)Heap.AlignedAlloc(16, 8192); m_tx_descs[i].Address = (uint)Paging.GetPhysicalFromVirtual(m_tx_buffers[i]); m_tx_descs[i].CMD = 0; m_tx_descs[i].CSO = 0; m_tx_descs[i].CSS = 0; m_tx_descs[i].Length = 0; m_tx_descs[i].Special = 0; m_tx_descs[i].STA = 0; } /** * Set tx address to device */ *(uint *)(m_register_base + REG_TDBAL) = (uint)Paging.GetPhysicalFromVirtual(m_tx_descs); *(uint *)(m_register_base + REG_TDBAH) = 0; /** * Setup total length */ *(uint *)(m_register_base + REG_TDLEN) = NUM_TX_DESCRIPTIORS * (uint)sizeof(TX_DESC); *(uint *)(m_register_base + REG_TDH) = 0; *(uint *)(m_register_base + REG_TDT) = 0; /** * Setup transmit control register */ *(uint *)(m_register_base + REG_TCTL) = REG_TCTL_EN | REG_TCTL_PSP; }
/// <summary> /// Alocate queue /// </summary> /// <param name="sqID">Submission Queue ID</param> /// <returns>Queue</returns> private unsafe NVMe_Queue AllocQueue(int sqID) { NVMe_Queue queue = new NVMe_Queue(); queue.SQID = sqID; queue.SubmissionQueue = (NVMe_Submission_Item *)Heap.AlignedAlloc(0x1000, sizeof(NVMe_Submission_Item) * mQueueSize); queue.CompletionQueue = (NVMe_Completion_Item *)Heap.AlignedAlloc(0x1000, sizeof(NVMe_Completion_Item) * mQueueSize); Memory.Memclear(queue.SubmissionQueue, sizeof(NVMe_Submission_Item) * mQueueSize); Memory.Memclear(queue.CompletionQueue, sizeof(NVMe_Completion_Item) * mQueueSize); queue.mSubmissionMutex = new Mutex(); queue.Max = mQueueSize; queue.Tail = 0; uint tail = (uint)mTailsAndHeads + (uint)((2 * sqID) * (sizeof(int) << mStride)); uint head = (uint)mTailsAndHeads + (uint)((2 * sqID + 1) * (sizeof(int) << mStride)); queue.TailPtr = (int *)tail; queue.HeadPtr = (int *)head; return(queue); }
private static unsafe void InitCard() { // Card register needs to be 32-byte aligned CARD_REG *reg = (CARD_REG *)Heap.AlignedAlloc(0x1000, sizeof(CARD_REG)); reg->MODE = 0x0180; // TLEN and RLEN are the 2log of their descriptor lengths shifted to the left by 4 reg->TLEN = 8 << 4; reg->RLEN = 8 << 4; for (int i = 0; i < 6; i++) { reg->MAC[i] = m_mac[i]; } reg->first_rec_entry = (uint)Paging.GetPhysicalFromVirtual(Util.ObjectToVoidPtr(m_rx_descriptors)); reg->first_transmit_entry = (uint)Paging.GetPhysicalFromVirtual(Util.ObjectToVoidPtr(m_tx_descriptors)); uint reg_adr = (uint)Paging.GetPhysicalFromVirtual(reg); writeCSR(0x01, (ushort)(reg_adr & 0xFFFF)); writeCSR(0x02, (ushort)((reg_adr >> 16) & 0xFFFF)); }
/// <summary> /// Clones the context from another thread /// </summary> /// <param name="context">The other thread context</param> public void CloneFrom(IThreadContext context) { X86ThreadContext source = (X86ThreadContext)context; // Stack createStacks(); Memory.Memcpy(m_kernelStackStart, source.m_kernelStackStart, KernelStackSize + UserStackSize); int diffStack = (int)source.m_stack - (int)source.m_stackStart; int diffKernelStack = (int)source.m_kernelStack - (int)source.m_kernelStackStart; m_stack = (int *)((int)m_stackStart + diffStack); m_kernelStack = (int *)((int)m_kernelStackStart + diffKernelStack); // FPU context m_FPUContext = Heap.AlignedAlloc(16, 512); Memory.Memcpy(m_FPUContext, source.m_FPUContext, 512); // Update stack references within the system stack itself int diffRegs = (int)source.m_sysRegs - (int)source.m_stackStart; int diffESP = source.m_sysRegs->ESP - (int)source.m_stackStart; m_sysRegs = (RegsDirect *)((int)m_stackStart + diffRegs); m_sysRegs->ESP = (int)m_stackStart + diffESP; // Write stack m_stack = writeSchedulerStack(m_stack, (void *)m_sysRegs->ESP, UserspaceCS, UserspaceDS, (void *)m_sysRegs->EIP); RegsDirect *ptr = (RegsDirect *)m_stack; ptr->EBX = m_sysRegs->EBX; ptr->ECX = m_sysRegs->ECX; ptr->EDX = m_sysRegs->EDX; ptr->EBP = m_sysRegs->EBP; ptr->ESI = m_sysRegs->ESI; ptr->EDI = m_sysRegs->EDI; }
/// <summary> /// ATA transfer /// </summary> /// <param name="info">AHCI port info</param> /// <param name="offset">LBA</param> /// <param name="count">Num of sectors</param> /// <param name="buffer">Buffer ptr</param> /// <param name="write">Write action?</param> /// <returns></returns> public int AtaTransfer(AHCIPortInfo info, int offset, int count, byte *buffer, bool write) { AHCI_Port_registers *portReg = info.PortRegisters; portReg->IS = 0; int fullCount = count * 512; int headerNumber = findFreeCommandHeader(info); if (headerNumber == -1) { return(0); } AHCI_Command_header *header = info.CommandHeader + headerNumber; header->Options = (ushort)((sizeof(AHCI_REG_H2D) / 4) | ((write? CMD_HEAD_WRITE: CMD_HEAD_READ))); int prdtl = (fullCount / 2024) + 1; header->Prdtl = (ushort)prdtl; byte *curBuf = buffer; int curOffset = 0; AHCI_Command_table_entry *cmdTable = (AHCI_Command_table_entry *)Heap.AlignedAlloc(128, sizeof(AHCI_Command_table_entry) + (sizeof(AHCI_PRDT_Entry) * prdtl)); Memory.Memclear(cmdTable, sizeof(AHCI_Command_table_entry) + (sizeof(AHCI_PRDT_Entry) * prdtl)); header->CTBA = (uint)Paging.GetPhysicalFromVirtual(cmdTable); for (int i = 0; i < header->Prdtl - 1; i++) { AHCI_PRDT_Entry *entry = (AHCI_PRDT_Entry *)((int)cmdTable + sizeof(AHCI_Command_table_entry) + (sizeof(AHCI_PRDT_Entry) * i)); entry->DBA = (uint)Paging.GetPhysicalFromVirtual(curBuf); entry->DBAU = 0x00; entry->Misc = 2023; curBuf += 2024; curOffset += 2024; } AHCI_PRDT_Entry *lastEntry = (AHCI_PRDT_Entry *)((int)cmdTable + sizeof(AHCI_Command_table_entry) + (sizeof(AHCI_PRDT_Entry) * (prdtl - 1))); lastEntry->DBA = (uint)Paging.GetPhysicalFromVirtual(curBuf); lastEntry->DBAU = 0x00; lastEntry->Misc = (fullCount - curOffset) - 1; AHCI_REG_H2D *fis = (AHCI_REG_H2D *)cmdTable->CFIS; fis->FisType = (int)AHCI_FIS.REG_H2D; fis->Command = ATA_CMD_READ_DMA_EX; fis->Options = (1 << 7); fis->LBA0 = (byte)(offset & 0xFF); fis->LBA1 = (byte)((offset >> 8) & 0xFF); fis->LBA2 = (byte)((offset >> 16) & 0xFF); fis->Device = (1 << 6); fis->LBA3 = 0x00; fis->LBA4 = 0x00; fis->LBA5 = 0x00; fis->CountLo = (byte)(count & 0xFF); fis->CountHi = (byte)((count >> 8) & 0xFF); // Wait until port ready while ((info.PortRegisters->TFD & (ATA_DEV_BUSY | ATA_DEV_DRQ)) > 0) { Tasking.Yield(); } info.PortRegisters->CI = (uint)(1 << headerNumber); while (true) { if ((info.PortRegisters->CI & (1 << headerNumber)) == 0) { break; } Tasking.Yield(); } if ((info.PortRegisters->IS & PxIS_TFES) > 0) { return(0); } return(0); }
/// <summary> /// Initalize port /// </summary> /// <param name="portInfo">Port info</param> private void initPort(AHCIPortInfo portInfo) { AHCI_Port_registers *portReg = mPorts + portInfo.PortNumber; portInfo.CommandHeader = (AHCI_Command_header *)Heap.AlignedAlloc(4048, sizeof(AHCI_Command_header) * NUM_CMD_HEADERS); Memory.Memset(portInfo.CommandHeader, 0xFF, sizeof(AHCI_Command_header) * NUM_CMD_HEADERS); portInfo.Type = GetPortType(portReg); // Port found? if (portInfo.Type == AHCI_PORT_TYPE.NO) { return; } // NOTE: We support only SATA for now.. if (portInfo.Type != AHCI_PORT_TYPE.SATA) { switch (portInfo.Type) { case AHCI_PORT_TYPE.PM: Console.Write("[AHCI] Unsupported type PM found on port "); Console.WriteNum(portInfo.PortNumber); Console.WriteLine(""); break; case AHCI_PORT_TYPE.SATAPI: Console.Write("[AHCI] Unsupported type SATAPI found on port "); Console.WriteNum(portInfo.PortNumber); Console.WriteLine(""); break; case AHCI_PORT_TYPE.SEMB: Console.Write("[AHCI] Unsupported type SEMB found on port "); Console.WriteNum(portInfo.PortNumber); Console.WriteLine(""); break; } return; } stopPort(portReg); AHCI_Received_FIS *Fises = (AHCI_Received_FIS *)Heap.AlignedAlloc(256, sizeof(AHCI_Received_FIS)); Memory.Memclear(Fises, sizeof(AHCI_Received_FIS)); portReg->CLB = (uint)Paging.GetPhysicalFromVirtual(portInfo.CommandHeader); portReg->CLBU = 0x00; portReg->FB = (uint)Paging.GetPhysicalFromVirtual(Fises); portReg->FBU = 0x00; AHCI_Command_table_entry *cmdTable = (AHCI_Command_table_entry *)Heap.AlignedAlloc(128, sizeof(AHCI_Command_table_entry)); Memory.Memclear(cmdTable, sizeof(AHCI_Command_table_entry)); for (int i = 0; i < NUM_CMD_HEADERS; i++) { portInfo.CommandHeader[i].Prdtl = 0; portInfo.CommandHeader[i].CTBA = (uint)cmdTable; portInfo.CommandHeader[i].CTBAU = 0x00; } startPort(portReg); portInfo.PortRegisters = portReg; char *name = (char *)Heap.Alloc(5); name[0] = 'H'; name[1] = 'D'; name[2] = 'A'; name[3] = (char)('0' + portInfo.PortNumber); name[4] = '\0'; string nameStr = Util.CharPtrToString(name); Node node = new Node(); node.Read = readImpl; //node.Write = writeImpl; AHCICookie cookie = new AHCICookie(); cookie.AHCI = this; cookie.PortInfo = portInfo; node.Cookie = cookie; Disk.InitalizeNode(node, nameStr); RootPoint dev = new RootPoint(nameStr, node); VFS.MountPointDevFS.AddEntry(dev); }
/// <summary> /// Executes an ELF file /// </summary> /// <param name="buffer">The buffer</param> /// <param name="size">The size of the ELF</param> /// <param name="argv">The arguments</param> /// <param name="flags">Spawn flags</param> /// <returns>The error code or PID</returns> public static unsafe int Execute(byte[] buffer, uint size, string[] argv, Task.SpawnFlags flags) { ELF32 *elf; fixed(byte *ptr = buffer) elf = (ELF32 *)ptr; if (!isValidELF(elf)) { return(-(int)ErrorCode.EINVAL); } // Get program header ProgramHeader *programHeader = (ProgramHeader *)((int)elf + elf->PhOff); uint virtAddress = programHeader->VirtAddress; void * allocated = Heap.AlignedAlloc(0x1000, (int)size); // Loop through every section for (uint i = 0; i < elf->ShNum; i++) { SectionHeader *section = getSection(elf, i); // Only loadable sections if (section->Address == 0) { continue; } uint offset = section->Address - virtAddress; // BSS if (section->Type == SectionHeaderType.SHT_NOBITS) { Memory.Memclear((void *)((uint)allocated + offset), (int)section->Size); } // Copy else { Memory.Memcpy((void *)((uint)allocated + offset), (void *)((uint)elf + section->Offset), (int)section->Size); } } // Count arguments int argc = 0; while (argv[argc] != null) { argc++; } // Make sure arguments are safe by copying them string[] argvClone = new string[argc + 1]; for (int i = 0; i < argc; i++) { argvClone[i] = String.Clone(argv[i]); } // Stack int[] initialStack = new int[2]; initialStack[0] = (int)Util.ObjectToVoidPtr(argvClone); initialStack[1] = argc; // Create thread Thread thread = new Thread(); thread.Context.CreateNewContext((void *)elf->Entry, 2, initialStack, false); Heap.Free(initialStack); CPU.CLI(); // Create task Task newTask = new Task(TaskPriority.NORMAL, flags); X86Context context = (X86Context)newTask.Context; context.CreateNewContext(false); newTask.AddThread(thread); newTask.AddUsedAddress(allocated); // Task info newTask.Name = argvClone[0]; newTask.CMDLine = Array.Join(argvClone, argc, " "); newTask.AddUsedAddress(newTask.CMDLine); // Argv clone freeing newTask.AddUsedAddress(argvClone); for (int i = 0; i < argc; i++) { newTask.AddUsedAddress(argvClone[i]); } // Map memory Paging.PageDirectory *newDirectory = context.PageDirVirtual; Paging.PageFlags pageFlags = Paging.PageFlags.Present | Paging.PageFlags.Writable | Paging.PageFlags.UserMode; for (uint j = 0; j < size; j += 0x1000) { // Note: the physical memory is not always a continuous block Paging.MapPage(newDirectory, (int)Paging.GetPhysicalFromVirtual((void *)((int)allocated + j)), (int)(virtAddress + j), pageFlags); } // Schedule task Tasking.ScheduleTask(newTask); CPU.STI(); return(newTask.PID); }
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); }
private unsafe static void initDevice(PciDevice dev) { if ((dev.BAR0.flags & Pci.BAR_IO) != 0) { Console.WriteLine("[EHCI] Only Memory mapped IO supported"); } /** * Enable bus mastering */ Pci.EnableBusMastering(dev); ulong barAddress = dev.BAR0.Address; EHCIController controller = new EHCIController(); controller.MemoryBase = (int)Paging.MapToVirtual(Paging.KernelDirectory, (int)barAddress, 20 * 0x1000, Paging.PageFlags.Writable | Paging.PageFlags.Present); controller.FrameList = (int *)Heap.AlignedAlloc(0x1000, sizeof(int) * 1024); controller.CapabilitiesRegisters = (EHCIHostCapRegister *)(controller.MemoryBase); controller.OperationalRegisters = controller.MemoryBase + (*controller.CapabilitiesRegisters).CapLength; controller.PortNum = ReadPorts(controller); controller.QueueHeadPool = (EHCIQueueHead *)Heap.AlignedAlloc(0x1000, sizeof(EHCIQueueHead) * MAX_HEADS); controller.TransferPool = (EHCITransferDescriptor *)Heap.AlignedAlloc(0x1000, sizeof(EHCITransferDescriptor) * MAX_TRANSFERS); controller.AsyncQueueHead = AllocateEmptyQH(controller); // Link to itself controller.AsyncQueueHead[0].Head = (int)controller.AsyncQueueHead | FL_QUEUEHEAD; controller.PeriodicQueuehead = AllocateEmptyQH(controller); for (int i = 0; i < 1024; i++) { controller.FrameList[i] = FL_QUEUEHEAD | (int)controller.PeriodicQueuehead; } // Set device *(int *)(controller.OperationalRegisters + REG_FRINDEX) = 0; *(int *)(controller.OperationalRegisters + REG_PERIODICLISTBASE) = (int)Paging.GetPhysicalFromVirtual(controller.FrameList); *(int *)(controller.OperationalRegisters + REG_ASYNCLISTADDR) = (int)Paging.GetPhysicalFromVirtual(controller.AsyncQueueHead); *(int *)(controller.OperationalRegisters + REG_CTRLDSSEGMENT) = 0; Console.Write("Periodic: "); Console.WriteHex((int)Paging.GetPhysicalFromVirtual(controller.FrameList)); Console.WriteLine(""); Console.Write("Periodic: "); Console.WriteHex((int)Paging.GetPhysicalFromVirtual(controller.FrameList)); Console.WriteLine(""); Console.Write("FRAME LIST PHYS: "); Console.WriteHex((int)Paging.GetPhysicalFromVirtual(controller.FrameList)); Console.WriteLine(""); Console.Write("FRAME LIST ENTRY: "); Console.WriteHex((int)controller.FrameList); Console.WriteLine(""); Console.Write("FRAME LIST ENTRY 1: "); Console.WriteHex(controller.FrameList[0]); Console.WriteLine(""); // Reset status *(int *)(controller.OperationalRegisters + REG_USBSTS) = 0x3F; // enable device *(int *)(controller.OperationalRegisters + REG_USBCMD) = USBCMD_PSE | USBCMD_RUN | USBCMD_ASPME | (ITC_8MICROFRAMES << USBCMD_ITC); // Wait till done while ((*(int *)(controller.OperationalRegisters + REG_USBSTS) & (1 << 12)) > 0) { CPU.HLT(); } Console.Write("[EHCI] Detected with "); Console.WriteHex(controller.PortNum); Console.WriteLine(" ports"); probe(controller); }
/// <summary> /// Creates a new signal context /// </summary> public X86SignalContext() { m_stackStart = (int *)Heap.AlignedAlloc(16, X86ThreadContext.UserStackSize); Stack = (int *)((int)m_stackStart + X86ThreadContext.UserStackSize); Sysregs = (RegsDirect *)Heap.Alloc(sizeof(RegsDirect)); }