Beispiel #1
0
        /// <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);
        }
Beispiel #2
0
        /// <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);
        }
Beispiel #3
0
 /// <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];
 }
Beispiel #4
0
        /// <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);
        }
Beispiel #5
0
        /// <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);
        }
Beispiel #6
0
        /// <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);
        }
Beispiel #7
0
        /// <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;
        }
Beispiel #8
0
        /// <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);
        }
Beispiel #9
0
        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));
        }
Beispiel #10
0
        /// <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;
        }
Beispiel #11
0
        /// <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);
        }
Beispiel #12
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);
        }
Beispiel #13
0
        /// <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);
        }
Beispiel #14
0
        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);
        }
Beispiel #15
0
        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);
        }
Beispiel #16
0
 /// <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));
 }