/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <trusty/trusty_dev.h>
#include <trusty/util.h>

/* 48-bit physical address bits 47:12 */

#define NS_PTE_PHYSADDR_SHIFT      12
#define NS_PTE_PHYSADDR(pte)       ((pte) & 0xFFFFFFFFF000ULL)

/* Access permissions bits 7:6
 *      EL0     EL1
 * 00   None    RW
 * 01   RW      RW
 * 10   None    RO
 * 11   RO      RO
 */
#define NS_PTE_AP_SHIFT                    6
#define NS_PTE_AP_MASK                     (0x3 << NS_PTE_AP_SHIFT)

/* Memory type and cache attributes bits 55:48 */
#define NS_PTE_MAIR_SHIFT                  48
#define NS_PTE_MAIR_MASK                   (0x00FFULL << NS_PTE_MAIR_SHIFT)

#define NS_PTE_MAIR_INNER_SHIFT            48
#define NS_PTE_MAIR_INNER_MASK             (0x000FULL << NS_PTE_MAIR_INNER_SHIFT)

#define NS_PTE_MAIR_OUTER_SHIFT            52
#define NS_PTE_MAIR_OUTER_MASK             (0x000FULL << NS_PTE_MAIR_OUTER_SHIFT)

/* Normal memory */
#define NS_MAIR_NORMAL_CACHED_WB_RWA       0xFF /* inner and outer write back read/write allocate */
#define NS_MAIR_NORMAL_CACHED_WT_RA        0xAA /* inner and outer write through read allocate */
#define NS_MAIR_NORMAL_CACHED_WB_RA        0xEE /* inner and outer write back, read allocate */
#define NS_MAIR_NORMAL_UNCACHED            0x44 /* uncached */

/* Device memory */
#define NS_MAIR_DEVICE_STRONGLY_ORDERED    0x00 /* nGnRnE (strongly ordered) */
#define NS_MAIR_DEVICE                     0x04 /* nGnRE  (device) */
#define NS_MAIR_DEVICE_GRE                 0x0C /* GRE */

/* shareable attributes bits 9:8 */
#define NS_PTE_SHAREABLE_SHIFT             8

#define NS_NON_SHAREABLE                   0x0
#define NS_OUTER_SHAREABLE                 0x2
#define NS_INNER_SHAREABLE                 0x3

typedef uintptr_t addr_t;
typedef uintptr_t vaddr_t;
typedef uintptr_t paddr_t;

#if NS_ARCH_ARM64

#define  PAR_F  (0x1 <<  0)

/*
 * ARM64
 */

/* Note: this will crash if called from user space */
static void arm64_write_ATS1ExW(uint64_t vaddr)
{
    uint64_t _current_el;

    __asm__ volatile("mrs %0, CurrentEL" : "=r" (_current_el));

    _current_el = (_current_el >> 2) & 0x3;
    switch (_current_el) {
    case 0x1:
        __asm__ volatile("at S1E1W, %0" :: "r" (vaddr));
        break;
    case 0x2:
        __asm__ volatile("at S1E2W, %0" :: "r" (vaddr));
        break;
    case 0x3:
    default:
        trusty_fatal("Unsupported execution state: EL%u\n", _current_el );
        break;
    }

    __asm__ volatile("isb" ::: "memory");
}

static uint64_t arm64_read_par64(void)
{
    uint64_t _val;
    __asm__ volatile("mrs %0, par_el1" : "=r" (_val));
    return _val;
}


static uint64_t va2par(vaddr_t va)
{
    uint64_t par;
    unsigned long irq_state;

    trusty_local_irq_disable(&irq_state);
    arm64_write_ATS1ExW(va);
    par = arm64_read_par64();
    trusty_local_irq_restore(&irq_state);

    return par;
}

static uint64_t par2attr(uint64_t par)
{
    uint64_t attr;

    /* set phys address */
    attr = NS_PTE_PHYSADDR(par);

    /* cache attributes */
    attr |= ((par >> 56) & 0xFF) << NS_PTE_MAIR_SHIFT;

    /* shareable attributes */
    attr |= ((par >> 7) & 0x03) << NS_PTE_SHAREABLE_SHIFT;

    /* the memory is writable and accessible so leave AP field 0 */
    attr |= 0x0 << NS_PTE_AP_SHIFT;

    return attr;
}

#else

#define  PAR_F     (0x1 <<  0)
#define  PAR_SS    (0x1 <<  1)
#define  PAR_SH    (0x1 <<  7)
#define  PAR_NOS   (0x1 << 10)
#define  PAR_LPAE  (0x1 << 11)

/*
 * ARM32
 */

/* Note: this will crash if called from user space */
static void arm_write_ATS1xW(uint64_t vaddr)
{
    uint32_t _cpsr;

    __asm__ volatile("mrs %0, cpsr" : "=r"(_cpsr));

    if ((_cpsr & 0xF) == 0xa)
        __asm__ volatile("mcr    p15, 4, %0, c7, c8, 1" : : "r"(vaddr));
    else
        __asm__ volatile("mcr    p15, 0, %0, c7, c8, 1" : : "r"(vaddr));
}

static uint64_t arm_read_par64(void)
{
    uint32_t lower, higher;

    __asm__ volatile(
        "mrc    p15, 0, %0, c7, c4, 0   \n"
        "tst    %0, #(1 << 11)      @ LPAE / long desc format\n"
        "moveq  %1, #0          \n"
        "mrrcne p15, 0, %0, %1, c7  \n"
         :"=r"(lower), "=r"(higher) : :
    );

    return ((uint64_t)higher << 32) | lower;
}


static uint8_t ish_to_mair[8] = {
    0x04, /* 0b000 Non cacheble */
    0x00, /* 0b001 Strongly ordered */
    0xF0, /* 0b010 reserved */
    0x04, /* 0b011 device */
    0xF0, /* 0b100 reserved */
    0x0F, /* 0b101 write back - write allocate */
    0x0A, /* 0b110 write through */
    0x0E, /* 0b111 write back - no write allocate */
};

static uint8_t osh_to_mair[4] = {
    0x00, /* 0b00   Non-cacheable */
    0x0F, /* 0b01   Write-back, Write-allocate */
    0x0A, /* 0b10   Write-through, no Write-allocate */
    0x0E, /* 0b11   Write-back, no Write-allocate */
};

static uint64_t par2attr(uint64_t par)
{
    uint64_t attr;

    if (par & PAR_LPAE) {
        /* set phys address */
        attr = NS_PTE_PHYSADDR(par);

        /* cache attributes */
        attr |= ((par >> 56) & 0xFF) << NS_PTE_MAIR_SHIFT;

        /* shareable attributes */
        attr |= ((par >> 7) & 0x03) << NS_PTE_SHAREABLE_SHIFT;

    } else {

        /* set phys address */
        trusty_assert((par & PAR_SS) == 0); /* super section not supported */
        attr = NS_PTE_PHYSADDR(par);

        /* cache attributes */
        uint64_t inner = ((uint64_t)ish_to_mair[(par >> 4) & 0x7]) << NS_PTE_MAIR_INNER_SHIFT;
        uint64_t outer = ((uint64_t)osh_to_mair[(par >> 2) & 0x3]) << NS_PTE_MAIR_OUTER_SHIFT;
        uint64_t cache_attributes = (outer << 4) | inner;

        /* Trusty does not support any kind of device memory, so we will force
         * cache attributes to be NORMAL UNCACHED on the Trusty side.
         */
        if (cache_attributes == NS_MAIR_DEVICE_STRONGLY_ORDERED) {
            attr |= ((uint64_t)NS_MAIR_NORMAL_UNCACHED << NS_PTE_MAIR_SHIFT);
        } else {
            attr |= inner;
            attr |= outer;
        }

        /* shareable attributes */
        if (par & PAR_SH) {
            /* how to handle NOS bit ? */
            attr |= ((uint64_t)NS_INNER_SHAREABLE) << NS_PTE_SHAREABLE_SHIFT;
        } else {
            attr |= ((uint64_t)NS_NON_SHAREABLE) << NS_PTE_SHAREABLE_SHIFT;
        }
    }

    /* the memory is writable and accessible so leave AP field 0 */
    attr |= 0x0 << NS_PTE_AP_SHIFT;

    return attr;
}

static uint64_t va2par(vaddr_t va)
{
    uint64_t par;
    unsigned long irq_state;

    trusty_local_irq_disable(&irq_state);
    arm_write_ATS1xW(va);
    par = arm_read_par64();
    trusty_local_irq_restore(&irq_state);

    return par;
}

#endif /* ARM64 */


int trusty_encode_page_info(struct ns_mem_page_info *inf, void *va)
{
    uint64_t par = va2par((vaddr_t)va);

    if (par & PAR_F) {
        return -1;
    }

    inf->attr = par2attr(par);

    return 0;
}

