Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
status_t virtio_block_init(struct virtio_device *dev, uint32_t host_features)
{
    LTRACEF("dev %p, host_features 0x%x\n", dev, host_features);

    /* allocate a new block device */
    struct virtio_block_dev *bdev = malloc(sizeof(struct virtio_block_dev));
    if (!bdev)
        return ERR_NO_MEMORY;

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

    bdev->dev = dev;
    dev->priv = bdev;

    bdev->blk_req = memalign(sizeof(struct virtio_blk_req), sizeof(struct virtio_blk_req));
#if WITH_KERNEL_VM
    arch_mmu_query((vaddr_t)bdev->blk_req, &bdev->blk_req_phys, NULL);
#else
    bdev->blk_freq_phys = (uint64_t)(uintptr_t)bdev->blk_req;
#endif
    LTRACEF("blk_req structure at %p (0x%lx phys)\n", bdev->blk_req, bdev->blk_req_phys);

#if WITH_KERNEL_VM
    arch_mmu_query((vaddr_t)&bdev->blk_response, &bdev->blk_response_phys, NULL);
#else
    bdev->blk_response_phys = (uint64_t)(uintptr_t)&bdev->blk_response;
#endif

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

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

    LTRACEF("capacity 0x%llx\n", config->capacity);
    LTRACEF("size_max 0x%x\n", config->size_max);
    LTRACEF("seg_max  0x%x\n", config->seg_max);
    LTRACEF("blk_size 0x%x\n", config->blk_size);

    /* 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, 256);

    /* set our irq handler */
    dev->irq_driver_callback = &virtio_block_irq_driver_callback;

    /* set DRIVER_OK */
    virtio_status_driver_ok(dev);

    /* construct the block device */
    static uint8_t found_index = 0;
    char buf[16];
    snprintf(buf, sizeof(buf), "virtio%u", found_index++);
    bio_initialize_bdev(&bdev->bdev, buf,
                        config->blk_size, config->capacity,
                        0, NULL);

    /* override our block device hooks */
    bdev->bdev.read_block = &virtio_bdev_read_block;
    bdev->bdev.write_block = &virtio_bdev_write_block;

    bio_register_device(&bdev->bdev);

    printf("found virtio block device of size %lld\n", config->capacity * config->blk_size);

    return NO_ERROR;
}