示例#1
0
文件: virtio-gpu.c 项目: 0xBADCA7/lk
status_t virtio_gpu_init(struct virtio_device *dev, uint32_t host_features)
{
    LTRACEF("dev %p, host_features 0x%x\n", dev, host_features);

    /* allocate a new gpu device */
    struct virtio_gpu_dev *gdev = malloc(sizeof(struct virtio_gpu_dev));
    if (!gdev)
        return ERR_NO_MEMORY;

    mutex_init(&gdev->lock);
    event_init(&gdev->io_event, false, EVENT_FLAG_AUTOUNSIGNAL);
    event_init(&gdev->flush_event, false, EVENT_FLAG_AUTOUNSIGNAL);

    gdev->dev = dev;
    dev->priv = gdev;

    gdev->pmode_id = -1;
    gdev->next_resource_id = 1;

    /* allocate memory for a gpu request */
#if WITH_KERNEL_VM
    gdev->gpu_request = pmm_alloc_kpage();
    gdev->gpu_request_phys = vaddr_to_paddr(gdev->gpu_request);
#else
    gdev->gpu_request = malloc(sizeof(struct virtio_gpu_resp_display_info)); // XXX get size better
    gdev->gpu_request_phys = (paddr_t)gdev->gpu_request;
#endif

    /* make sure the device is reset */
    virtio_reset_device(dev);

    volatile struct virtio_gpu_config *config = (struct virtio_gpu_config *)dev->config_ptr;
    dump_gpu_config(config);

    /* ack and set the driver status bit */
    virtio_status_acknowledge_driver(dev);

    // XXX check features bits and ack/nak them

    /* allocate a virtio ring */
    virtio_alloc_ring(dev, 0, 16);

    /* set our irq handler */
    dev->irq_driver_callback = &virtio_gpu_irq_driver_callback;
    dev->config_change_callback = &virtio_gpu_config_change_callback;

    /* set DRIVER_OK */
    virtio_status_driver_ok(dev);

    /* save the main device we've found */
    the_gdev = gdev;

    printf("found virtio gpu device\n");

    return NO_ERROR;
}
示例#2
0
文件: mmu.c 项目: taphier/lk
static status_t get_l2_table(uint32_t l1_index, paddr_t *ppa)
{
    status_t ret;
    paddr_t pa;
    uint32_t tt_entry;

    DEBUG_ASSERT(ppa);

    /* lookup an existing l2 pagetable */
    for (uint i = 0; i < L1E_PER_PAGE; i++) {
        tt_entry = arm_kernel_translation_table[ROUNDDOWN(l1_index, L1E_PER_PAGE) + i];
        if ((tt_entry & MMU_MEMORY_L1_DESCRIPTOR_MASK)
                == MMU_MEMORY_L1_DESCRIPTOR_PAGE_TABLE) {
            *ppa = (paddr_t)ROUNDDOWN(MMU_MEMORY_L1_PAGE_TABLE_ADDR(tt_entry), PAGE_SIZE)
                   + (PAGE_SIZE / L1E_PER_PAGE) * (l1_index & (L1E_PER_PAGE-1));
            return NO_ERROR;
        }
    }

    /* not found: allocate it */
    uint32_t *l2_va = pmm_alloc_kpage();
    if (!l2_va)
        return ERR_NO_MEMORY;

    /* wipe it clean to set no access */
    memset(l2_va, 0, PAGE_SIZE);

    /* get physical address */
    ret = arm_vtop((vaddr_t)l2_va, &pa);
    ASSERT(!ret);
    ASSERT(paddr_to_kvaddr(pa));

    DEBUG_ASSERT(IS_PAGE_ALIGNED((vaddr_t)l2_va));
    DEBUG_ASSERT(IS_PAGE_ALIGNED(pa));

    *ppa = pa + (PAGE_SIZE / L1E_PER_PAGE) * (l1_index & (L1E_PER_PAGE-1));

    LTRACEF("allocated pagetable at %p, pa 0x%lx, pa 0x%lx\n", l2_va, pa, *ppa);
    return NO_ERROR;
}