static virtual_addr_t __init find_root_system_descriptor(void) { struct acpi_search_area *carea = &acpi_areas[0]; virtual_addr_t area_map; virtual_addr_t rsdp_base = 0; virtual_size_t sz = 0; while (carea->area_name) { vmm_printf("Search for RSDP in %s... ", carea->area_name); sz = carea->phys_end - carea->phys_start; area_map = vmm_host_memmap(carea->phys_start, sz, VMM_MEMORY_FLAGS_NORMAL_NOCACHE); BUG_ON((void *)area_map == NULL); if ((rsdp_base = locate_rsdp_in_area(area_map, sz)) != 0) { vmm_printf("found.\n"); break; } rsdp_base = 0; carea++; vmm_host_memunmap(area_map); vmm_printf("not found.\n"); } if (likely(rsdp_base)) vmm_printf("RSDP Base: 0x%x\n", rsdp_base); return rsdp_base; }
int virtio_queue_setup(struct virtio_queue *vq, struct vmm_guest *guest, physical_addr_t guest_pfn, physical_size_t guest_page_size, u32 desc_count, u32 align) { int rc = 0; u32 reg_flags; physical_addr_t gphys_addr, hphys_addr; physical_size_t gphys_size, avail_size; if ((rc = virtio_queue_cleanup(vq))) { return rc; } gphys_addr = guest_pfn * guest_page_size; gphys_size = vring_size(desc_count, align); if ((rc = vmm_guest_physical_map(guest, gphys_addr, gphys_size, &hphys_addr, &avail_size, ®_flags))) { vmm_printf("Failed vmm_guest_physical_map\n"); return VMM_EFAIL; } if (!(reg_flags & VMM_REGION_ISRAM)) { return VMM_EINVALID; } if (avail_size < gphys_size) { return VMM_EINVALID; } vq->addr = (void *)vmm_host_memmap(hphys_addr, gphys_size, VMM_MEMORY_FLAGS_NORMAL); if (!vq->addr) { return VMM_ENOMEM; } vring_init(&vq->vring, desc_count, vq->addr, align); vq->guest = guest; vq->desc_count = desc_count; vq->align = align; vq->guest_pfn = guest_pfn; vq->guest_page_size = guest_page_size; vq->guest_addr = gphys_addr; vq->host_addr = hphys_addr; vq->total_size = gphys_size; return VMM_OK; }
struct mempool *mempool_raw_create(u32 entity_size, physical_addr_t phys, virtual_size_t size, u32 mem_flags) { u32 e; virtual_addr_t va; struct mempool *mp; if (!entity_size || (size < entity_size)) { return NULL; } mp = vmm_zalloc(sizeof(struct mempool)); if (!mp) { return NULL; } mp->type = MEMPOOL_TYPE_RAW; mp->entity_size = entity_size; mp->entity_count = udiv64(size, entity_size); mp->f = fifo_alloc(sizeof(virtual_addr_t), mp->entity_count); if (!mp->f) { vmm_free(mp); return NULL; } mp->entity_base = vmm_host_memmap(phys, size, mem_flags); if (!mp->entity_base) { fifo_free(mp->f); vmm_free(mp); return NULL; } mp->d.raw.phys = phys; mp->d.raw.size = size; mp->d.raw.mem_flags = mem_flags; for (e = 0; e < mp->entity_count; e++) { va = mp->entity_base + e * entity_size; fifo_enqueue(mp->f, &va, FALSE); } return mp; }