/*
 * Copyright (c) 2018 Virtuozzo International GmbH
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 *
 */

#include "qemu/osdep.h"
#include "addrspace.h"

static struct pa_block *pa_space_find_block(struct pa_space *ps, uint64_t pa)
{
    size_t i;

    for (i = 0; i < ps->block_nr; i++) {
        if (ps->block[i].paddr <= pa &&
                pa < ps->block[i].paddr + ps->block[i].size) {
            return ps->block + i;
        }
    }

    return NULL;
}

static uint8_t *pa_space_resolve(struct pa_space *ps, uint64_t pa)
{
    struct pa_block *block = pa_space_find_block(ps, pa);

    if (!block) {
        return NULL;
    }

    return block->addr + (pa - block->paddr);
}

static void pa_block_align(struct pa_block *b)
{
    uint64_t low_align = ((b->paddr - 1) | ELF2DMP_PAGE_MASK) + 1 - b->paddr;
    uint64_t high_align = (b->paddr + b->size) & ELF2DMP_PAGE_MASK;

    if (low_align == 0 && high_align == 0) {
        return;
    }

    if (low_align + high_align < b->size) {
        printf("Block 0x%"PRIx64"+:0x%"PRIx64" will be aligned to "
                "0x%"PRIx64"+:0x%"PRIx64"\n", b->paddr, b->size,
                b->paddr + low_align, b->size - low_align - high_align);
        b->size -= low_align + high_align;
    } else {
        printf("Block 0x%"PRIx64"+:0x%"PRIx64" is too small to align\n",
                b->paddr, b->size);
        b->size = 0;
    }

    b->addr += low_align;
    b->paddr += low_align;
}

int pa_space_create(struct pa_space *ps, QEMU_Elf *qemu_elf)
{
    Elf64_Half phdr_nr = elf_getphdrnum(qemu_elf->map);
    Elf64_Phdr *phdr = elf64_getphdr(qemu_elf->map);
    size_t block_i = 0;
    size_t i;

    ps->block_nr = 0;

    for (i = 0; i < phdr_nr; i++) {
        if (phdr[i].p_type == PT_LOAD) {
            ps->block_nr++;
        }
    }

    ps->block = malloc(sizeof(*ps->block) * ps->block_nr);
    if (!ps->block) {
        return 1;
    }

    for (i = 0; i < phdr_nr; i++) {
        if (phdr[i].p_type == PT_LOAD) {
            ps->block[block_i] = (struct pa_block) {
                .addr = (uint8_t *)qemu_elf->map + phdr[i].p_offset,
                .paddr = phdr[i].p_paddr,
                .size = phdr[i].p_filesz,
            };
            pa_block_align(&ps->block[block_i]);
            block_i = ps->block[block_i].size ? (block_i + 1) : block_i;
        }
    }

    ps->block_nr = block_i;

    return 0;
}

void pa_space_destroy(struct pa_space *ps)
{
    ps->block_nr = 0;
    free(ps->block);
}

void va_space_set_dtb(struct va_space *vs, uint64_t dtb)
{
    vs->dtb = dtb & 0x00ffffffffff000;
}

void va_space_create(struct va_space *vs, struct pa_space *ps, uint64_t dtb)
{
    vs->ps = ps;
    va_space_set_dtb(vs, dtb);
}

static uint64_t get_pml4e(struct va_space *vs, uint64_t va)
{
    uint64_t pa = (vs->dtb & 0xffffffffff000) | ((va & 0xff8000000000) >> 36);

    return *(uint64_t *)pa_space_resolve(vs->ps, pa);
}

static uint64_t get_pdpi(struct va_space *vs, uint64_t va, uint64_t pml4e)
{
    uint64_t pdpte_paddr = (pml4e & 0xffffffffff000) |
        ((va & 0x7FC0000000) >> 27);

    return *(uint64_t *)pa_space_resolve(vs->ps, pdpte_paddr);
}

static uint64_t pde_index(uint64_t va)
{
    return (va >> 21) & 0x1FF;
}

static uint64_t pdba_base(uint64_t pdpe)
{
    return pdpe & 0xFFFFFFFFFF000;
}

static uint64_t get_pgd(struct va_space *vs, uint64_t va, uint64_t pdpe)
{
    uint64_t pgd_entry = pdba_base(pdpe) + pde_index(va) * 8;

    return *(uint64_t *)pa_space_resolve(vs->ps, pgd_entry);
}

static uint64_t pte_index(uint64_t va)
{
    return (va >> 12) & 0x1FF;
}

static uint64_t ptba_base(uint64_t pde)
{
    return pde & 0xFFFFFFFFFF000;
}

static uint64_t get_pte(struct va_space *vs, uint64_t va, uint64_t pgd)
{
    uint64_t pgd_val = ptba_base(pgd) + pte_index(va) * 8;

    return *(uint64_t *)pa_space_resolve(vs->ps, pgd_val);
}

static uint64_t get_paddr(uint64_t va, uint64_t pte)
{
    return (pte & 0xFFFFFFFFFF000) | (va & 0xFFF);
}

static bool is_present(uint64_t entry)
{
    return entry & 0x1;
}

static bool page_size_flag(uint64_t entry)
{
    return entry & (1 << 7);
}

static uint64_t get_1GB_paddr(uint64_t va, uint64_t pdpte)
{
    return (pdpte & 0xfffffc0000000) | (va & 0x3fffffff);
}

static uint64_t get_2MB_paddr(uint64_t va, uint64_t pgd_entry)
{
    return (pgd_entry & 0xfffffffe00000) | (va & 0x00000001fffff);
}

static uint64_t va_space_va2pa(struct va_space *vs, uint64_t va)
{
    uint64_t pml4e, pdpe, pgd, pte;

    pml4e = get_pml4e(vs, va);
    if (!is_present(pml4e)) {
        return INVALID_PA;
    }

    pdpe = get_pdpi(vs, va, pml4e);
    if (!is_present(pdpe)) {
        return INVALID_PA;
    }

    if (page_size_flag(pdpe)) {
        return get_1GB_paddr(va, pdpe);
    }

    pgd = get_pgd(vs, va, pdpe);
    if (!is_present(pgd)) {
        return INVALID_PA;
    }

    if (page_size_flag(pgd)) {
        return get_2MB_paddr(va, pgd);
    }

    pte = get_pte(vs, va, pgd);
    if (!is_present(pte)) {
        return INVALID_PA;
    }

    return get_paddr(va, pte);
}

void *va_space_resolve(struct va_space *vs, uint64_t va)
{
    uint64_t pa = va_space_va2pa(vs, va);

    if (pa == INVALID_PA) {
        return NULL;
    }

    return pa_space_resolve(vs->ps, pa);
}

int va_space_rw(struct va_space *vs, uint64_t addr,
        void *buf, size_t size, int is_write)
{
    while (size) {
        uint64_t page = addr & ELF2DMP_PFN_MASK;
        size_t s = (page + ELF2DMP_PAGE_SIZE) - addr;
        void *ptr;

        s = (s > size) ? size : s;

        ptr = va_space_resolve(vs, addr);
        if (!ptr) {
            return 1;
        }

        if (is_write) {
            memcpy(ptr, buf, s);
        } else {
            memcpy(buf, ptr, s);
        }

        size -= s;
        buf = (uint8_t *)buf + s;
        addr += s;
    }

    return 0;
}
