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); }
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)); } }
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; } } }