Beispiel #1
0
static void start_io_operation(const struct dma_io_data *data)
{
    uint8_t cmd = data->cmd;
    uint8_t bm_cmd = data->bm_cmd;
    uint16_t count = data->sector_count;
    uint64_t start = data->start_sector;
    struct drive *d = &drives[data->drive];
    struct prd_entry *prdt_address = &prdt[d->bus];

    /* Prepare PRDT */
    prdt_address->physical_addr = data->buffer;
    prdt_address->size = data->size;
    prdt_address->reserved = 0x8000;    /* Set it as the last PRD entry */

    /* Stop DMA first, and then send command. */
    out_byte(d->bm_reg + IDE_BUS_MASTER_CMD, 0x0);
    out_dword(d->bm_reg + IDE_BUS_MASTER_PRDT, CAST_VIRTUAL_TO_PHYSICAL(prdt_address));
    out_byte(d->bm_reg + IDE_BUS_MASTER_CMD, bm_cmd | 0x1);

    if (d->lba48)
    {
        out_byte(d->base_reg + IDE_REGISTER_DRIVE_SELECT, 0x40 | (d->drive << 4));
        out_byte(d->base_reg + IDE_REGISTER_SECTOR_COUNT, (count >> 8) & 0xff);
        out_byte(d->base_reg + IDE_REGISTER_LBA_LO, (start >> 24) & 0xff);
        out_byte(d->base_reg + IDE_REGISTER_LBA_MID, (start >> 32) & 0xff);
        out_byte(d->base_reg + IDE_REGISTER_LBA_HI, (start >> 40) & 0xff);
        out_byte(d->base_reg + IDE_REGISTER_SECTOR_COUNT, count & 0xff);
        out_byte(d->base_reg + IDE_REGISTER_LBA_LO, start & 0xff);
        out_byte(d->base_reg + IDE_REGISTER_LBA_MID, (start >> 8) & 0xff);
        out_byte(d->base_reg + IDE_REGISTER_LBA_HI, (start >> 16) & 0xff);
    }
Beispiel #2
0
static inline void slab_list_destroy(struct slab_page *head)
{
    struct slab_page *slab = slab_list_first(head);
    while (slab != head)
    {
        /* Remove from list */
        struct slab_page *temp = slab;
        slab = slab->next;
        slab_list_remove(temp);

        /* Free physical memory page */
        pmm_free_page_address(CAST_VIRTUAL_TO_PHYSICAL(temp));
    }
}
Beispiel #3
0
void scheduler()
{
    for (;;)
    {
        struct process *proc =
            current_proc ? current_proc->next : list_head.next;

        /* Find a runnable process */
        while (proc == &list_head || proc->state != PROC_STATE_RUNNING)
        {
            if (proc != &list_head && proc->state == PROC_STATE_DEAD)
            {
                /* Release the dead process */
                struct process *dead = proc;
                proc = proc->next;
                sched_remove(dead);
                proc_free(dead);
            }
            else
            {
                proc = proc->next;
            }
        }

        close_int();
        current_proc = proc;

        /* Update TSS */
        tss.ss0 = KERNEL_DATA_SELECTOR;
        tss.esp0 = proc->kernel_stack;
        flush_tss();

        /* Change to process virtual address space */
        set_cr3(CAST_VIRTUAL_TO_PHYSICAL(proc->page_dir));

        if (!proc->context)
            init_context(proc);

        switch_kcontext(&sched_context, proc->context);

        /* Call schedule task */
        if (sched_task)
        {
            sched_task(current_proc);
            sched_task = NULL;
        }
    }
}