root/arch/hexagon/include/asm/hexagon_vm.h
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Declarations for to Hexagon Virtal Machine.
 *
 * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
 */

#ifndef ASM_HEXAGON_VM_H
#define ASM_HEXAGON_VM_H

/*
 * In principle, a Linux kernel for the VM could
 * selectively define the virtual instructions
 * as inline assembler macros, but for a first pass,
 * we'll use subroutines for both the VM and the native
 * kernels.  It's costing a subroutine call/return,
 * but it makes for a single set of entry points
 * for tracing/debugging.
 */

#define HVM_TRAP1_VMVERSION             0
#define HVM_TRAP1_VMRTE                 1
#define HVM_TRAP1_VMSETVEC              2
#define HVM_TRAP1_VMSETIE               3
#define HVM_TRAP1_VMGETIE               4
#define HVM_TRAP1_VMINTOP               5
#define HVM_TRAP1_VMCLRMAP              10
#define HVM_TRAP1_VMNEWMAP              11
#define HVM_TRAP1_FORMERLY_VMWIRE       12
#define HVM_TRAP1_VMCACHE               13
#define HVM_TRAP1_VMGETTIME             14
#define HVM_TRAP1_VMSETTIME             15
#define HVM_TRAP1_VMWAIT                16
#define HVM_TRAP1_VMYIELD               17
#define HVM_TRAP1_VMSTART               18
#define HVM_TRAP1_VMSTOP                19
#define HVM_TRAP1_VMVPID                20
#define HVM_TRAP1_VMSETREGS             21
#define HVM_TRAP1_VMGETREGS             22
#define HVM_TRAP1_VMTIMEROP             24

#ifndef __ASSEMBLY__

enum VM_CACHE_OPS {
        hvmc_ickill,
        hvmc_dckill,
        hvmc_l2kill,
        hvmc_dccleaninva,
        hvmc_icinva,
        hvmc_idsync,
        hvmc_fetch_cfg
};

enum VM_INT_OPS {
        hvmi_nop,
        hvmi_globen,
        hvmi_globdis,
        hvmi_locen,
        hvmi_locdis,
        hvmi_affinity,
        hvmi_get,
        hvmi_peek,
        hvmi_status,
        hvmi_post,
        hvmi_clear
};

extern void _K_VM_event_vector(void);

void __vmrte(void);
long __vmsetvec(void *);
long __vmsetie(long);
long __vmgetie(void);
long __vmintop(enum VM_INT_OPS, long, long, long, long);
long __vmclrmap(void *, unsigned long);
long __vmnewmap(void *);
long __vmcache(enum VM_CACHE_OPS op, unsigned long addr, unsigned long len);
unsigned long long __vmgettime(void);
long __vmsettime(unsigned long long);
long __vmstart(void *, void *);
void __vmstop(void);
long __vmwait(void);
void __vmyield(void);
long __vmvpid(void);

static inline long __vmcache_ickill(void)
{
        return __vmcache(hvmc_ickill, 0, 0);
}

static inline long __vmcache_dckill(void)
{
        return __vmcache(hvmc_dckill, 0, 0);
}

static inline long __vmcache_l2kill(void)
{
        return __vmcache(hvmc_l2kill, 0, 0);
}

static inline long __vmcache_dccleaninva(unsigned long addr, unsigned long len)
{
        return __vmcache(hvmc_dccleaninva, addr, len);
}

static inline long __vmcache_icinva(unsigned long addr, unsigned long len)
{
        return __vmcache(hvmc_icinva, addr, len);
}

static inline long __vmcache_idsync(unsigned long addr,
                                           unsigned long len)
{
        return __vmcache(hvmc_idsync, addr, len);
}

static inline long __vmcache_fetch_cfg(unsigned long val)
{
        return __vmcache(hvmc_fetch_cfg, val, 0);
}

/* interrupt operations  */

static inline long __vmintop_nop(void)
{
        return __vmintop(hvmi_nop, 0, 0, 0, 0);
}

static inline long __vmintop_globen(long i)
{
        return __vmintop(hvmi_globen, i, 0, 0, 0);
}

static inline long __vmintop_globdis(long i)
{
        return __vmintop(hvmi_globdis, i, 0, 0, 0);
}

static inline long __vmintop_locen(long i)
{
        return __vmintop(hvmi_locen, i, 0, 0, 0);
}

static inline long __vmintop_locdis(long i)
{
        return __vmintop(hvmi_locdis, i, 0, 0, 0);
}

static inline long __vmintop_affinity(long i, long cpu)
{
        return __vmintop(hvmi_affinity, i, cpu, 0, 0);
}

static inline long __vmintop_get(void)
{
        return __vmintop(hvmi_get, 0, 0, 0, 0);
}

static inline long __vmintop_peek(void)
{
        return __vmintop(hvmi_peek, 0, 0, 0, 0);
}

static inline long __vmintop_status(long i)
{
        return __vmintop(hvmi_status, i, 0, 0, 0);
}

static inline long __vmintop_post(long i)
{
        return __vmintop(hvmi_post, i, 0, 0, 0);
}

static inline long __vmintop_clear(long i)
{
        return __vmintop(hvmi_clear, i, 0, 0, 0);
}

#else /* Only assembly code should reference these */

#endif /* __ASSEMBLY__ */

/*
 * Constants for virtual instruction parameters and return values
 */

/* vmnewmap arguments */

#define VM_TRANS_TYPE_LINEAR 0
#define VM_TRANS_TYPE_TABLE 1
#define VM_TLB_INVALIDATE_FALSE 0
#define VM_TLB_INVALIDATE_TRUE 1

/* vmsetie arguments */

#define VM_INT_DISABLE  0
#define VM_INT_ENABLE   1

/* vmsetimask arguments */

#define VM_INT_UNMASK   0
#define VM_INT_MASK     1

#define VM_NEWMAP_TYPE_LINEAR   0
#define VM_NEWMAP_TYPE_PGTABLES 1


/*
 * Event Record definitions useful to both C and Assembler
 */

/* VMEST Layout */

#define HVM_VMEST_UM_SFT        31
#define HVM_VMEST_UM_MSK        1
#define HVM_VMEST_IE_SFT        30
#define HVM_VMEST_IE_MSK        1
#define HVM_VMEST_SS_SFT        29
#define HVM_VMEST_SS_MSK        1
#define HVM_VMEST_EVENTNUM_SFT  16
#define HVM_VMEST_EVENTNUM_MSK  0xff
#define HVM_VMEST_CAUSE_SFT     0
#define HVM_VMEST_CAUSE_MSK     0xffff

/*
 * The initial program gets to find a system environment descriptor
 * on its stack when it begins execution. The first word is a version
 * code to indicate what is there.  Zero means nothing more.
 */

#define HEXAGON_VM_SED_NULL     0

/*
 * Event numbers for vector binding
 */

#define HVM_EV_RESET            0
#define HVM_EV_MACHCHECK        1
#define HVM_EV_GENEX            2
#define HVM_EV_TRAP             8
#define HVM_EV_INTR             15
/* These shoud be nuked as soon as we know the VM is up to spec v0.1.1 */
#define HVM_EV_INTR_0           16
#define HVM_MAX_INTR            240

/*
 * Cause values for General Exception
 */

#define HVM_GE_C_BUS    0x01
#define HVM_GE_C_XPROT  0x11
#define HVM_GE_C_XUSER  0x14
#define HVM_GE_C_INVI   0x15
#define HVM_GE_C_PRIVI  0x1B
#define HVM_GE_C_XMAL   0x1C
#define HVM_GE_C_WREG   0x1D
#define HVM_GE_C_PCAL   0x1E
#define HVM_GE_C_RMAL   0x20
#define HVM_GE_C_WMAL   0x21
#define HVM_GE_C_RPROT  0x22
#define HVM_GE_C_WPROT  0x23
#define HVM_GE_C_RUSER  0x24
#define HVM_GE_C_WUSER  0x25
#define HVM_GE_C_CACHE  0x28

/*
 * Cause codes for Machine Check
 */

#define HVM_MCHK_C_DOWN         0x00
#define HVM_MCHK_C_BADSP        0x01
#define HVM_MCHK_C_BADEX        0x02
#define HVM_MCHK_C_BADPT        0x03
#define HVM_MCHK_C_REGWR        0x29

#endif