Commit 4a1d38c4 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/amarkovic/tags/mips-queue-may-19-2019-v3' into staging



MIPS queue for May 19th, 2019 - v3

# gpg: Signature made Sun 26 May 2019 17:07:07 BST
# gpg:                using RSA key D4972A8967F75A65
# gpg: Good signature from "Aleksandar Markovic <amarkovic@wavecomp.com>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 8526 FBF1 5DA3 811F 4A01  DD75 D497 2A89 67F7 5A65

* remotes/amarkovic/tags/mips-queue-may-19-2019-v3:
  BootLinuxSshTest: Test some userspace commands on Malta
  target/mips: realign comments to fix checkpatch warnings
  target/mips: add or remove space to fix checkpatch errors
  linux-user: fix __NR_semtimedop undeclared error
  mips: Decide to map PAGE_EXEC in map_address
  target/mips: Refactor and fix INSERT.<B|H|W|D> instructions
  target/mips: Refactor and fix COPY_U.<B|H|W> instructions
  target/mips: Refactor and fix COPY_S.<B|H|W|D> instructions
  target/mips: Fix MSA instructions ST.<B|H|W|D> on big endian host
  target/mips: Fix MSA instructions LD.<B|H|W|D> on big endian host
  target/mips: Make the results of MOD_<U|S>.<B|H|W|D> the same as on hardware
  target/mips: Make the results of DIV_<U|S>.<B|H|W|D> the same as on hardware

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 4bade282 c47c336e
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -934,6 +934,7 @@ M: Aurelien Jarno <aurelien@aurel32.net>
R: Aleksandar Rikalo <arikalo@wavecomp.com>
R: Aleksandar Rikalo <arikalo@wavecomp.com>
S: Maintained
S: Maintained
F: hw/mips/mips_malta.c
F: hw/mips/mips_malta.c
F: tests/acceptance/linux_ssh_mips_malta.py


Mipssim
Mipssim
M: Aleksandar Markovic <amarkovic@wavecomp.com>
M: Aleksandar Markovic <amarkovic@wavecomp.com>
+16 −8
Original line number Original line Diff line number Diff line
@@ -763,14 +763,7 @@ safe_syscall2(int, nanosleep, const struct timespec *, req,
safe_syscall4(int, clock_nanosleep, const clockid_t, clock, int, flags,
safe_syscall4(int, clock_nanosleep, const clockid_t, clock, int, flags,
              const struct timespec *, req, struct timespec *, rem)
              const struct timespec *, req, struct timespec *, rem)
#endif
#endif
#ifdef __NR_msgsnd
#if !defined(__NR_msgsnd) || !defined(__NR_msgrcv) || !defined(__NR_semtimedop)
safe_syscall4(int, msgsnd, int, msgid, const void *, msgp, size_t, sz,
              int, flags)
safe_syscall5(int, msgrcv, int, msgid, void *, msgp, size_t, sz,
              long, msgtype, int, flags)
safe_syscall4(int, semtimedop, int, semid, struct sembuf *, tsops,
              unsigned, nsops, const struct timespec *, timeout)
#else
/* This host kernel architecture uses a single ipc syscall; fake up
/* This host kernel architecture uses a single ipc syscall; fake up
 * wrappers for the sub-operations to hide this implementation detail.
 * wrappers for the sub-operations to hide this implementation detail.
 * Annoyingly we can't include linux/ipc.h to get the constant definitions
 * Annoyingly we can't include linux/ipc.h to get the constant definitions
@@ -785,14 +778,29 @@ safe_syscall4(int, semtimedop, int, semid, struct sembuf *, tsops,


safe_syscall6(int, ipc, int, call, long, first, long, second, long, third,
safe_syscall6(int, ipc, int, call, long, first, long, second, long, third,
              void *, ptr, long, fifth)
              void *, ptr, long, fifth)
#endif
#ifdef __NR_msgsnd
safe_syscall4(int, msgsnd, int, msgid, const void *, msgp, size_t, sz,
              int, flags)
#else
static int safe_msgsnd(int msgid, const void *msgp, size_t sz, int flags)
static int safe_msgsnd(int msgid, const void *msgp, size_t sz, int flags)
{
{
    return safe_ipc(Q_IPCCALL(0, Q_MSGSND), msgid, sz, flags, (void *)msgp, 0);
    return safe_ipc(Q_IPCCALL(0, Q_MSGSND), msgid, sz, flags, (void *)msgp, 0);
}
}
#endif
#ifdef __NR_msgrcv
safe_syscall5(int, msgrcv, int, msgid, void *, msgp, size_t, sz,
              long, msgtype, int, flags)
#else
static int safe_msgrcv(int msgid, void *msgp, size_t sz, long type, int flags)
static int safe_msgrcv(int msgid, void *msgp, size_t sz, long type, int flags)
{
{
    return safe_ipc(Q_IPCCALL(1, Q_MSGRCV), msgid, sz, flags, msgp, type);
    return safe_ipc(Q_IPCCALL(1, Q_MSGRCV), msgid, sz, flags, msgp, type);
}
}
#endif
#ifdef __NR_semtimedop
safe_syscall4(int, semtimedop, int, semid, struct sembuf *, tsops,
              unsigned, nsops, const struct timespec *, timeout)
#else
static int safe_semtimedop(int semid, struct sembuf *tsops, unsigned nsops,
static int safe_semtimedop(int semid, struct sembuf *tsops, unsigned nsops,
                           const struct timespec *timeout)
                           const struct timespec *timeout)
{
{
+116 −93
Original line number Original line Diff line number Diff line
@@ -37,7 +37,8 @@ union fpr_t {
/* FPU/MSA register mapping is not tested on big-endian hosts. */
/* FPU/MSA register mapping is not tested on big-endian hosts. */
    wr_t     wr;   /* vector data */
    wr_t     wr;   /* vector data */
};
};
/* define FP_ENDIAN_IDX to access the same location
/*
 *define FP_ENDIAN_IDX to access the same location
 * in the fpr_t union regardless of the host endianness
 * in the fpr_t union regardless of the host endianness
 */
 */
#if defined(HOST_WORDS_BIGENDIAN)
#if defined(HOST_WORDS_BIGENDIAN)
@@ -71,15 +72,28 @@ struct CPUMIPSFPUContext {
#define FCR31_FS 24
#define FCR31_FS 24
#define FCR31_ABS2008 19
#define FCR31_ABS2008 19
#define FCR31_NAN2008 18
#define FCR31_NAN2008 18
#define SET_FP_COND(num,env)     do { ((env).fcr31) |= ((num) ? (1 << ((num) + 24)) : (1 << 23)); } while(0)
#define SET_FP_COND(num, env)     do { ((env).fcr31) |=                 \
#define CLEAR_FP_COND(num,env)   do { ((env).fcr31) &= ~((num) ? (1 << ((num) + 24)) : (1 << 23)); } while(0)
                                       ((num) ? (1 << ((num) + 24)) :   \
#define GET_FP_COND(env)         ((((env).fcr31 >> 24) & 0xfe) | (((env).fcr31 >> 23) & 0x1))
                                                (1 << 23));             \
                                     } while (0)
#define CLEAR_FP_COND(num, env)   do { ((env).fcr31) &=                 \
                                       ~((num) ? (1 << ((num) + 24)) :  \
                                                 (1 << 23));            \
                                     } while (0)
#define GET_FP_COND(env)         ((((env).fcr31 >> 24) & 0xfe) |        \
                                 (((env).fcr31 >> 23) & 0x1))
#define GET_FP_CAUSE(reg)        (((reg) >> 12) & 0x3f)
#define GET_FP_CAUSE(reg)        (((reg) >> 12) & 0x3f)
#define GET_FP_ENABLE(reg)       (((reg) >>  7) & 0x1f)
#define GET_FP_ENABLE(reg)       (((reg) >>  7) & 0x1f)
#define GET_FP_FLAGS(reg)        (((reg) >>  2) & 0x1f)
#define GET_FP_FLAGS(reg)        (((reg) >>  2) & 0x1f)
#define SET_FP_CAUSE(reg,v)      do { (reg) = ((reg) & ~(0x3f << 12)) | ((v & 0x3f) << 12); } while(0)
#define SET_FP_CAUSE(reg, v)      do { (reg) = ((reg) & ~(0x3f << 12)) | \
#define SET_FP_ENABLE(reg,v)     do { (reg) = ((reg) & ~(0x1f <<  7)) | ((v & 0x1f) << 7); } while(0)
                                               ((v & 0x3f) << 12);       \
#define SET_FP_FLAGS(reg,v)      do { (reg) = ((reg) & ~(0x1f <<  2)) | ((v & 0x1f) << 2); } while(0)
                                     } while (0)
#define SET_FP_ENABLE(reg, v)     do { (reg) = ((reg) & ~(0x1f <<  7)) | \
                                               ((v & 0x1f) << 7);        \
                                     } while (0)
#define SET_FP_FLAGS(reg, v)      do { (reg) = ((reg) & ~(0x1f <<  2)) | \
                                               ((v & 0x1f) << 2);        \
                                     } while (0)
#define UPDATE_FP_FLAGS(reg, v)   do { (reg) |= ((v & 0x1f) << 2); } while (0)
#define UPDATE_FP_FLAGS(reg, v)   do { (reg) |= ((v & 0x1f) << 2); } while (0)
#define FP_INEXACT        1
#define FP_INEXACT        1
#define FP_UNDERFLOW      2
#define FP_UNDERFLOW      2
@@ -963,9 +977,11 @@ struct CPUMIPSState {
    /* TMASK defines different execution modes */
    /* TMASK defines different execution modes */
#define MIPS_HFLAG_TMASK  0x1F5807FF
#define MIPS_HFLAG_TMASK  0x1F5807FF
#define MIPS_HFLAG_MODE   0x00007 /* execution modes                    */
#define MIPS_HFLAG_MODE   0x00007 /* execution modes                    */
    /* The KSU flags must be the lowest bits in hflags. The flag order
    /*
       must be the same as defined for CP0 Status. This allows to use
     * The KSU flags must be the lowest bits in hflags. The flag order
       the bits as the value of mmu_idx. */
     * must be the same as defined for CP0 Status. This allows to use
     * the bits as the value of mmu_idx.
     */
#define MIPS_HFLAG_KSU    0x00003 /* kernel/supervisor/user mode mask   */
#define MIPS_HFLAG_KSU    0x00003 /* kernel/supervisor/user mode mask   */
#define MIPS_HFLAG_UM     0x00002 /* user mode flag                     */
#define MIPS_HFLAG_UM     0x00002 /* user mode flag                     */
#define MIPS_HFLAG_SM     0x00001 /* supervisor mode flag               */
#define MIPS_HFLAG_SM     0x00001 /* supervisor mode flag               */
@@ -975,18 +991,22 @@ struct CPUMIPSState {
#define MIPS_HFLAG_CP0    0x00010 /* CP0 enabled                        */
#define MIPS_HFLAG_CP0    0x00010 /* CP0 enabled                        */
#define MIPS_HFLAG_FPU    0x00020 /* FPU enabled                        */
#define MIPS_HFLAG_FPU    0x00020 /* FPU enabled                        */
#define MIPS_HFLAG_F64    0x00040 /* 64-bit FPU enabled                 */
#define MIPS_HFLAG_F64    0x00040 /* 64-bit FPU enabled                 */
    /* True if the MIPS IV COP1X instructions can be used.  This also
    /*
       controls the non-COP1X instructions RECIP.S, RECIP.D, RSQRT.S
     * True if the MIPS IV COP1X instructions can be used.  This also
       and RSQRT.D.  */
     * controls the non-COP1X instructions RECIP.S, RECIP.D, RSQRT.S
     * and RSQRT.D.
     */
#define MIPS_HFLAG_COP1X  0x00080 /* COP1X instructions enabled         */
#define MIPS_HFLAG_COP1X  0x00080 /* COP1X instructions enabled         */
#define MIPS_HFLAG_RE     0x00100 /* Reversed endianness                */
#define MIPS_HFLAG_RE     0x00100 /* Reversed endianness                */
#define MIPS_HFLAG_AWRAP  0x00200 /* 32-bit compatibility address wrapping */
#define MIPS_HFLAG_AWRAP  0x00200 /* 32-bit compatibility address wrapping */
#define MIPS_HFLAG_M16    0x00400 /* MIPS16 mode flag                   */
#define MIPS_HFLAG_M16    0x00400 /* MIPS16 mode flag                   */
#define MIPS_HFLAG_M16_SHIFT 10
#define MIPS_HFLAG_M16_SHIFT 10
    /* If translation is interrupted between the branch instruction and
    /*
     * If translation is interrupted between the branch instruction and
     * the delay slot, record what type of branch it is so that we can
     * the delay slot, record what type of branch it is so that we can
     * resume translation properly.  It might be possible to reduce
     * resume translation properly.  It might be possible to reduce
     * this from three bits to two.  */
     * this from three bits to two.
     */
#define MIPS_HFLAG_BMASK_BASE  0x803800
#define MIPS_HFLAG_BMASK_BASE  0x803800
#define MIPS_HFLAG_B      0x00800 /* Unconditional branch               */
#define MIPS_HFLAG_B      0x00800 /* Unconditional branch               */
#define MIPS_HFLAG_BC     0x01000 /* Conditional branch                 */
#define MIPS_HFLAG_BC     0x01000 /* Conditional branch                 */
@@ -1073,8 +1093,10 @@ void mips_cpu_list(void);
extern void cpu_wrdsp(uint32_t rs, uint32_t mask_num, CPUMIPSState *env);
extern void cpu_wrdsp(uint32_t rs, uint32_t mask_num, CPUMIPSState *env);
extern uint32_t cpu_rddsp(uint32_t mask_num, CPUMIPSState *env);
extern uint32_t cpu_rddsp(uint32_t mask_num, CPUMIPSState *env);


/* MMU modes definitions. We carefully match the indices with our
/*
   hflags layout. */
 * MMU modes definitions. We carefully match the indices with our
 * hflags layout.
 */
#define MMU_MODE0_SUFFIX _kernel
#define MMU_MODE0_SUFFIX _kernel
#define MMU_MODE1_SUFFIX _super
#define MMU_MODE1_SUFFIX _super
#define MMU_MODE2_SUFFIX _user
#define MMU_MODE2_SUFFIX _user
@@ -1097,7 +1119,8 @@ static inline int cpu_mmu_index (CPUMIPSState *env, bool ifetch)


#include "exec/cpu-all.h"
#include "exec/cpu-all.h"


/* Memory access type :
/*
 * Memory access type :
 * may be needed for precise access rights control and precise exceptions.
 * may be needed for precise access rights control and precise exceptions.
 */
 */
enum {
enum {
+8 −5
Original line number Original line Diff line number Diff line
@@ -43,7 +43,7 @@ int no_mmu_map_address (CPUMIPSState *env, hwaddr *physical, int *prot,
                        target_ulong address, int rw, int access_type)
                        target_ulong address, int rw, int access_type)
{
{
    *physical = address;
    *physical = address;
    *prot = PAGE_READ | PAGE_WRITE;
    *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
    return TLBRET_MATCH;
    return TLBRET_MATCH;
}
}


@@ -61,7 +61,7 @@ int fixed_mmu_map_address (CPUMIPSState *env, hwaddr *physical, int *prot,
    else
    else
        *physical = address;
        *physical = address;


    *prot = PAGE_READ | PAGE_WRITE;
    *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
    return TLBRET_MATCH;
    return TLBRET_MATCH;
}
}


@@ -101,6 +101,9 @@ int r4k_map_address (CPUMIPSState *env, hwaddr *physical, int *prot,
                *prot = PAGE_READ;
                *prot = PAGE_READ;
                if (n ? tlb->D1 : tlb->D0)
                if (n ? tlb->D1 : tlb->D0)
                    *prot |= PAGE_WRITE;
                    *prot |= PAGE_WRITE;
                if (!(n ? tlb->XI1 : tlb->XI0)) {
                    *prot |= PAGE_EXEC;
                }
                return TLBRET_MATCH;
                return TLBRET_MATCH;
            }
            }
            return TLBRET_DIRTY;
            return TLBRET_DIRTY;
@@ -182,7 +185,7 @@ static int get_seg_physical_address(CPUMIPSState *env, hwaddr *physical,
    } else {
    } else {
        /* The segment is unmapped */
        /* The segment is unmapped */
        *physical = physical_base | (real_address & segmask);
        *physical = physical_base | (real_address & segmask);
        *prot = PAGE_READ | PAGE_WRITE;
        *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
        return TLBRET_MATCH;
        return TLBRET_MATCH;
    }
    }
}
}
@@ -907,7 +910,7 @@ bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
    }
    }
    if (ret == TLBRET_MATCH) {
    if (ret == TLBRET_MATCH) {
        tlb_set_page(cs, address & TARGET_PAGE_MASK,
        tlb_set_page(cs, address & TARGET_PAGE_MASK,
                     physical & TARGET_PAGE_MASK, prot | PAGE_EXEC,
                     physical & TARGET_PAGE_MASK, prot,
                     mmu_idx, TARGET_PAGE_SIZE);
                     mmu_idx, TARGET_PAGE_SIZE);
        return true;
        return true;
    }
    }
@@ -927,7 +930,7 @@ bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                                       access_type, mips_access_type, mmu_idx);
                                       access_type, mips_access_type, mmu_idx);
            if (ret == TLBRET_MATCH) {
            if (ret == TLBRET_MATCH) {
                tlb_set_page(cs, address & TARGET_PAGE_MASK,
                tlb_set_page(cs, address & TARGET_PAGE_MASK,
                             physical & TARGET_PAGE_MASK, prot | PAGE_EXEC,
                             physical & TARGET_PAGE_MASK, prot,
                             mmu_idx, TARGET_PAGE_SIZE);
                             mmu_idx, TARGET_PAGE_SIZE);
                return true;
                return true;
            }
            }
+13 −3
Original line number Original line Diff line number Diff line
@@ -876,9 +876,7 @@ DEF_HELPER_5(msa_hsub_u_df, void, env, i32, i32, i32, i32)


DEF_HELPER_5(msa_sldi_df, void, env, i32, i32, i32, i32)
DEF_HELPER_5(msa_sldi_df, void, env, i32, i32, i32, i32)
DEF_HELPER_5(msa_splati_df, void, env, i32, i32, i32, i32)
DEF_HELPER_5(msa_splati_df, void, env, i32, i32, i32, i32)
DEF_HELPER_5(msa_copy_s_df, void, env, i32, i32, i32, i32)

DEF_HELPER_5(msa_copy_u_df, void, env, i32, i32, i32, i32)
DEF_HELPER_5(msa_insert_df, void, env, i32, i32, i32, i32)
DEF_HELPER_5(msa_insve_df, void, env, i32, i32, i32, i32)
DEF_HELPER_5(msa_insve_df, void, env, i32, i32, i32, i32)
DEF_HELPER_3(msa_ctcmsa, void, env, tl, i32)
DEF_HELPER_3(msa_ctcmsa, void, env, tl, i32)
DEF_HELPER_2(msa_cfcmsa, tl, env, i32)
DEF_HELPER_2(msa_cfcmsa, tl, env, i32)
@@ -938,6 +936,18 @@ DEF_HELPER_4(msa_pcnt_df, void, env, i32, i32, i32)
DEF_HELPER_4(msa_nloc_df, void, env, i32, i32, i32)
DEF_HELPER_4(msa_nloc_df, void, env, i32, i32, i32)
DEF_HELPER_4(msa_nlzc_df, void, env, i32, i32, i32)
DEF_HELPER_4(msa_nlzc_df, void, env, i32, i32, i32)


DEF_HELPER_4(msa_copy_s_b, void, env, i32, i32, i32)
DEF_HELPER_4(msa_copy_s_h, void, env, i32, i32, i32)
DEF_HELPER_4(msa_copy_s_w, void, env, i32, i32, i32)
DEF_HELPER_4(msa_copy_s_d, void, env, i32, i32, i32)
DEF_HELPER_4(msa_copy_u_b, void, env, i32, i32, i32)
DEF_HELPER_4(msa_copy_u_h, void, env, i32, i32, i32)
DEF_HELPER_4(msa_copy_u_w, void, env, i32, i32, i32)
DEF_HELPER_4(msa_insert_b, void, env, i32, i32, i32)
DEF_HELPER_4(msa_insert_h, void, env, i32, i32, i32)
DEF_HELPER_4(msa_insert_w, void, env, i32, i32, i32)
DEF_HELPER_4(msa_insert_d, void, env, i32, i32, i32)

DEF_HELPER_4(msa_fclass_df, void, env, i32, i32, i32)
DEF_HELPER_4(msa_fclass_df, void, env, i32, i32, i32)
DEF_HELPER_4(msa_ftrunc_s_df, void, env, i32, i32, i32)
DEF_HELPER_4(msa_ftrunc_s_df, void, env, i32, i32, i32)
DEF_HELPER_4(msa_ftrunc_u_df, void, env, i32, i32, i32)
DEF_HELPER_4(msa_ftrunc_u_df, void, env, i32, i32, i32)
Loading