Beispiel #1
0
static void
sys_ipa_to_pa(vm_t* vm, seL4_UserContext* regs)
{
    seL4_ARM_Page_GetAddress_t ret;
    uint32_t ipa;
    seL4_CPtr cap;
    ipa = regs->r0;
    cap = vspace_get_cap(vm_get_vspace(vm), (void*)ipa);
    if (cap == seL4_CapNull) {
        void* mapped_address;
        mapped_address = map_vm_ram(vm, ipa);
        if (mapped_address == NULL) {
            printf("Could not map address for IPA translation\n");
            return;
        }
        cap = vspace_get_cap(vm_get_vspace(vm), (void*)ipa);
        assert(cap != seL4_CapNull);
    }

    ret = seL4_ARM_Page_GetAddress(cap);
    assert(!ret.error);
    DSTRACE("IPA translation syscall from [%s]: 0x%08x->0x%08x\n",
            vm->name, ipa, ret.paddr);
    regs->r0 = ret.paddr;
}
Beispiel #2
0
int
vm_install_tk1_usb_passthrough_device(vm_t* vm)
{

    /* Add the device */
    void *addr = map_vm_device(vm, dev_usb.pstart, dev_usb.pstart, seL4_AllRights);
    if (addr == NULL) {
        ZF_LOGE("map_vm_device returned NULL");
        return -1;
    }
    void *vmm_addr = vspace_share_mem(vm_get_vspace(vm), vm_get_vmm_vspace(vm), addr, 1,
    seL4_PageBits, seL4_AllRights, 0);
    if (vmm_addr == NULL) {
        ZF_LOGE("vspace_share_mem returned NULL");
        return -1;
    }

    int err = vm_add_device(vm, &dev_usb);
    if (err) {
        ZF_LOGE("vm_add_device returned error: %d", err);
        return -1;
    }
    err = vm_register_reboot_callback(vm, usb_vm_reboot_hook, vmm_addr);
    if (err) {
        ZF_LOGE("vm_register_reboot_callback returned error: %d", err);
        return -1;
    }

    return 0;
}
Beispiel #3
0
uintptr_t
vm_ipa_to_pa(vm_t* vm, uintptr_t ipa_base, size_t size)
{
    seL4_ARM_Page_GetAddress_t ret;
    uintptr_t pa_base = 0;
    uintptr_t ipa;
    vspace_t *vspace;
    vspace = vm_get_vspace(vm);
    ipa = ipa_base;
    do {
        seL4_CPtr cap;
        int bits;
        /* Find the cap */
        cap = vspace_get_cap(vspace, (void*)ipa);
        if (cap == seL4_CapNull) {
            return 0;
        }
        /* Find mapping size */
        bits = vspace_get_cookie(vspace, (void*)ipa);
        assert(bits == 12 || bits == 21);
        /* Find the physical address */
        ret = seL4_ARM_Page_GetAddress(cap);
        if (ret.error) {
            return 0;
        }
        if (ipa == ipa_base) {
            /* Record the result */
            pa_base = ret.paddr + (ipa & MASK(bits));
            /* From here on, ipa and ret.paddr will be aligned */
            ipa &= ~MASK(bits);
        } else {
            /* Check for a contiguous mapping */
            if (ret.paddr - pa_base != ipa - ipa_base) {
                return 0;
            }
        }
        ipa += BIT(bits);
    } while (ipa - ipa_base < size);
    return pa_base;
}
Beispiel #4
0
int
vm_copyout_atags(vm_t* vm, struct atag_list* atags, uint32_t addr)
{
    vspace_t *vm_vspace, *vmm_vspace;
    void* vm_addr, *vmm_addr, *buf;
    reservation_t res;
    vka_t* vka;
    vka_object_t frame;
    size_t size;
    struct atag_list* atag_cur;
    int err;

    vka = vm->vka;
    vm_addr = (void*)(addr & ~0xfff);
    vm_vspace = vm_get_vspace(vm);
    vmm_vspace = vm->vmm_vspace;

    /* Make sure we don't cross a page boundary
     * NOTE: the next page will usually be used by linux for PT!
     */
    for (size = 0, atag_cur = atags; atag_cur != NULL; atag_cur = atag_cur->next) {
        size += atags_size_bytes(atag_cur);
    }
    size += 8; /* NULL tag */
    assert((addr & 0xfff) + size < 0x1000);

    /* Create a frame (and a copy for the VMM) */
    err = vka_alloc_frame(vka, 12, &frame);
    assert(!err);
    if (err) {
        return -1;
    }
    /* Map the frame to the VMM */
    vmm_addr = vspace_map_pages(vmm_vspace, &frame.cptr, NULL, seL4_AllRights, 1, 12, 0);
    assert(vmm_addr);

    /* Copy in the atags */
    buf = vmm_addr + (addr & 0xfff);
    for (atag_cur = atags; atag_cur != NULL; atag_cur = atag_cur->next) {
        int tag_size = atags_size_bytes(atag_cur);
        DVM("ATAG copy 0x%x<-0x%x %d\n", (uint32_t)buf, (uint32_t)atag_cur->hdr, tag_size);
        memcpy(buf, atag_cur->hdr, tag_size);
        buf += tag_size;
    }
    /* NULL tag terminator */
    memset(buf, 0, 8);

    /* Unmap the page and map it into the VM */
    vspace_unmap_pages(vmm_vspace, vmm_addr, 1, 12, NULL);
    res = vspace_reserve_range_at(vm_vspace, vm_addr, 0x1000, seL4_AllRights, 0);
    assert(res.res);
    if (!res.res) {
        vka_free_object(vka, &frame);
        return -1;
    }
    err = vspace_map_pages_at_vaddr(vm_vspace, &frame.cptr, NULL, vm_addr, 1, 12, res);
    vspace_free_reservation(vm_vspace, res);
    assert(!err);
    if (err) {
        printf("Failed to provide memory\n");
        vka_free_object(vka, &frame);
        return -1;
    }

    return 0;
}