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