MIPS patches 2015-06-26
Changes: * MIPS UHI semihosting support * microMIPS32 R6 support -----BEGIN PGP SIGNATURE----- iQEcBAABAgAGBQJVjR6JAAoJEFIRjjwLKdprY+kH/1ZOyKB2GDRH7xqzvZ19m7Tk y4WXmPFyPcjCDlFk9JcPVK5m4NRqmQzlC9nlc/DaGEIbF7N4r+yq2r0ektBDrrWu GLhn39OCQQKJkdSvDacNQCUdoPt9fbka0xpBcc/r+VNKNZUB9VXiSz48idTW0zRm y6wPe/A7I86s3a5QpRvfzgTONwZaZwXLmoSmQaDRYqYC1zF6CE00NUguenAd2ldD wr8tJ6mRtnfNSj9HulHKhFxzqhPnxQ3lNASeSP81b3LOYnN+3Q5srw85qaYkdKih yw9+SWnPukjVGjksKCiSDxhqZKkBg6A5YsV7N09Nb7lIXgie0Hur+seGDnKsMVU= =A75b -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/lalrae/tags/mips-20150626' into staging MIPS patches 2015-06-26 Changes: * MIPS UHI semihosting support * microMIPS32 R6 support # gpg: Signature made Fri Jun 26 10:42:33 2015 BST using RSA key ID 0B29DA6B # gpg: Good signature from "Leon Alrae <leon.alrae@imgtec.com>" # 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: 8DD3 2F98 5495 9D66 35D4 4FC0 5211 8E3C 0B29 DA6B * remotes/lalrae/tags/mips-20150626: target-mips: add mips32r6-generic CPU definition target-mips: microMIPS32 R6 POOL16{A, C} instructions target-mips: microMIPS32 R6 Major instructions target-mips: microMIPS32 R6 POOL32{I, C} instructions target-mips: microMIPS32 R6 POOL32F instructions target-mips: microMIPS32 R6 POOL32A{XF} instructions target-mips: microMIPS32 R6 branches and jumps target-mips: add microMIPS32 R6 opcode enum target-mips: signal RI for removed instructions in microMIPS R6 target-mips: raise RI exceptions when FIR.PS = 0 target-mips: rearrange gen_compute_compact_branch target-mips: refactor {D}LSA, {D}ALIGN, {D}BITSWAP target-mips: remove an unused argument target-mips: add microMIPS TLBINV, TLBINVF target-mips: fix {RD, WR}PGPR in microMIPS target-mips: convert host to MIPS errno values when required target-mips: add Unified Hosting Interface (UHI) support target-mips: remove identical code in different branch hw/mips: Do not clear BEV for MIPS malta kernel load include/softmmu-semi.h: Make semihosting support 64-bit clean Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
ccb0c7e122
@ -53,6 +53,7 @@
|
||||
#include "qemu/error-report.h"
|
||||
#include "hw/empty_slot.h"
|
||||
#include "sysemu/kvm.h"
|
||||
#include "exec/semihost.h"
|
||||
|
||||
//#define DEBUG_BOARD_INIT
|
||||
|
||||
@ -634,7 +635,13 @@ static void write_bootloader (CPUMIPSState *env, uint8_t *base,
|
||||
|
||||
/* Second part of the bootloader */
|
||||
p = (uint32_t *) (base + 0x580);
|
||||
stl_p(p++, 0x24040002); /* addiu a0, zero, 2 */
|
||||
|
||||
if (semihosting_get_argc()) {
|
||||
/* Preserve a0 content as arguments have been passed */
|
||||
stl_p(p++, 0x00000000); /* nop */
|
||||
} else {
|
||||
stl_p(p++, 0x24040002); /* addiu a0, zero, 2 */
|
||||
}
|
||||
stl_p(p++, 0x3c1d0000 | (((ENVP_ADDR - 64) >> 16) & 0xffff)); /* lui sp, high(ENVP_ADDR) */
|
||||
stl_p(p++, 0x37bd0000 | ((ENVP_ADDR - 64) & 0xffff)); /* ori sp, sp, low(ENVP_ADDR) */
|
||||
stl_p(p++, 0x3c050000 | ((ENVP_ADDR >> 16) & 0xffff)); /* lui a1, high(ENVP_ADDR) */
|
||||
@ -887,7 +894,7 @@ static void main_cpu_reset(void *opaque)
|
||||
read only location. The kernel location and the arguments table
|
||||
location does not change. */
|
||||
if (loaderparams.kernel_filename) {
|
||||
env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
|
||||
env->CP0_Status &= ~(1 << CP0St_ERL);
|
||||
}
|
||||
|
||||
malta_mips_config(cpu);
|
||||
|
@ -9,14 +9,14 @@
|
||||
#ifndef SOFTMMU_SEMI_H
|
||||
#define SOFTMMU_SEMI_H 1
|
||||
|
||||
static inline uint32_t softmmu_tget32(CPUArchState *env, uint32_t addr)
|
||||
static inline uint32_t softmmu_tget32(CPUArchState *env, target_ulong addr)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)&val, 4, 0);
|
||||
return tswap32(val);
|
||||
}
|
||||
static inline uint32_t softmmu_tget8(CPUArchState *env, uint32_t addr)
|
||||
static inline uint32_t softmmu_tget8(CPUArchState *env, target_ulong addr)
|
||||
{
|
||||
uint8_t val;
|
||||
|
||||
@ -28,7 +28,8 @@ static inline uint32_t softmmu_tget8(CPUArchState *env, uint32_t addr)
|
||||
#define get_user_u8(arg, p) ({ arg = softmmu_tget8(env, p) ; 0; })
|
||||
#define get_user_ual(arg, p) get_user_u32(arg, p)
|
||||
|
||||
static inline void softmmu_tput32(CPUArchState *env, uint32_t addr, uint32_t val)
|
||||
static inline void softmmu_tput32(CPUArchState *env,
|
||||
target_ulong addr, uint32_t val)
|
||||
{
|
||||
val = tswap32(val);
|
||||
cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)&val, 4, 1);
|
||||
@ -36,8 +37,8 @@ static inline void softmmu_tput32(CPUArchState *env, uint32_t addr, uint32_t val
|
||||
#define put_user_u32(arg, p) ({ softmmu_tput32(env, p, arg) ; 0; })
|
||||
#define put_user_ual(arg, p) put_user_u32(arg, p)
|
||||
|
||||
static void *softmmu_lock_user(CPUArchState *env, uint32_t addr, uint32_t len,
|
||||
int copy)
|
||||
static void *softmmu_lock_user(CPUArchState *env,
|
||||
target_ulong addr, target_ulong len, int copy)
|
||||
{
|
||||
uint8_t *p;
|
||||
/* TODO: Make this something that isn't fixed size. */
|
||||
@ -48,7 +49,7 @@ static void *softmmu_lock_user(CPUArchState *env, uint32_t addr, uint32_t len,
|
||||
return p;
|
||||
}
|
||||
#define lock_user(type, p, len, copy) softmmu_lock_user(env, p, len, copy)
|
||||
static char *softmmu_lock_user_string(CPUArchState *env, uint32_t addr)
|
||||
static char *softmmu_lock_user_string(CPUArchState *env, target_ulong addr)
|
||||
{
|
||||
char *p;
|
||||
char *s;
|
||||
|
@ -3345,20 +3345,22 @@ Set OpenBIOS nvram @var{variable} to given @var{value} (PPC, SPARC only).
|
||||
ETEXI
|
||||
DEF("semihosting", 0, QEMU_OPTION_semihosting,
|
||||
"-semihosting semihosting mode\n",
|
||||
QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | QEMU_ARCH_LM32)
|
||||
QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | QEMU_ARCH_LM32 |
|
||||
QEMU_ARCH_MIPS)
|
||||
STEXI
|
||||
@item -semihosting
|
||||
@findex -semihosting
|
||||
Enable semihosting mode (ARM, M68K, Xtensa only).
|
||||
Enable semihosting mode (ARM, M68K, Xtensa, MIPS only).
|
||||
ETEXI
|
||||
DEF("semihosting-config", HAS_ARG, QEMU_OPTION_semihosting_config,
|
||||
"-semihosting-config [enable=on|off][,target=native|gdb|auto][,arg=str[,...]]\n" \
|
||||
" semihosting configuration\n",
|
||||
QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | QEMU_ARCH_LM32)
|
||||
QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | QEMU_ARCH_LM32 |
|
||||
QEMU_ARCH_MIPS)
|
||||
STEXI
|
||||
@item -semihosting-config [enable=on|off][,target=native|gdb|auto][,arg=str[,...]]
|
||||
@findex -semihosting-config
|
||||
Enable and configure semihosting (ARM, M68K, Xtensa only).
|
||||
Enable and configure semihosting (ARM, M68K, Xtensa, MIPS only).
|
||||
@table @option
|
||||
@item target=@code{native|gdb|auto}
|
||||
Defines where the semihosting calls will be addressed, to QEMU (@code{native})
|
||||
|
@ -1,4 +1,4 @@
|
||||
obj-y += translate.o dsp_helper.o op_helper.o lmi_helper.o helper.o cpu.o
|
||||
obj-y += gdbstub.o msa_helper.o
|
||||
obj-y += gdbstub.o msa_helper.o mips-semi.o
|
||||
obj-$(CONFIG_SOFTMMU) += machine.o
|
||||
obj-$(CONFIG_KVM) += kvm.o
|
||||
|
@ -1,6 +1,8 @@
|
||||
DEF_HELPER_3(raise_exception_err, noreturn, env, i32, int)
|
||||
DEF_HELPER_2(raise_exception, noreturn, env, i32)
|
||||
|
||||
DEF_HELPER_1(do_semihosting, void, env)
|
||||
|
||||
#ifdef TARGET_MIPS64
|
||||
DEF_HELPER_4(sdl, void, env, tl, tl, int)
|
||||
DEF_HELPER_4(sdr, void, env, tl, tl, int)
|
||||
|
358
target-mips/mips-semi.c
Normal file
358
target-mips/mips-semi.c
Normal file
@ -0,0 +1,358 @@
|
||||
/*
|
||||
* Unified Hosting Interface syscalls.
|
||||
*
|
||||
* Copyright (c) 2015 Imagination Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include "cpu.h"
|
||||
#include "exec/helper-proto.h"
|
||||
#include "exec/softmmu-semi.h"
|
||||
#include "exec/semihost.h"
|
||||
|
||||
typedef enum UHIOp {
|
||||
UHI_exit = 1,
|
||||
UHI_open = 2,
|
||||
UHI_close = 3,
|
||||
UHI_read = 4,
|
||||
UHI_write = 5,
|
||||
UHI_lseek = 6,
|
||||
UHI_unlink = 7,
|
||||
UHI_fstat = 8,
|
||||
UHI_argc = 9,
|
||||
UHI_argnlen = 10,
|
||||
UHI_argn = 11,
|
||||
UHI_plog = 13,
|
||||
UHI_assert = 14,
|
||||
UHI_pread = 19,
|
||||
UHI_pwrite = 20,
|
||||
UHI_link = 22
|
||||
} UHIOp;
|
||||
|
||||
typedef struct UHIStat {
|
||||
int16_t uhi_st_dev;
|
||||
uint16_t uhi_st_ino;
|
||||
uint32_t uhi_st_mode;
|
||||
uint16_t uhi_st_nlink;
|
||||
uint16_t uhi_st_uid;
|
||||
uint16_t uhi_st_gid;
|
||||
int16_t uhi_st_rdev;
|
||||
uint64_t uhi_st_size;
|
||||
uint64_t uhi_st_atime;
|
||||
uint64_t uhi_st_spare1;
|
||||
uint64_t uhi_st_mtime;
|
||||
uint64_t uhi_st_spare2;
|
||||
uint64_t uhi_st_ctime;
|
||||
uint64_t uhi_st_spare3;
|
||||
uint64_t uhi_st_blksize;
|
||||
uint64_t uhi_st_blocks;
|
||||
uint64_t uhi_st_spare4[2];
|
||||
} UHIStat;
|
||||
|
||||
enum UHIOpenFlags {
|
||||
UHIOpen_RDONLY = 0x0,
|
||||
UHIOpen_WRONLY = 0x1,
|
||||
UHIOpen_RDWR = 0x2,
|
||||
UHIOpen_APPEND = 0x8,
|
||||
UHIOpen_CREAT = 0x200,
|
||||
UHIOpen_TRUNC = 0x400,
|
||||
UHIOpen_EXCL = 0x800
|
||||
};
|
||||
|
||||
/* Errno values taken from asm-mips/errno.h */
|
||||
static uint16_t host_to_mips_errno[] = {
|
||||
[ENAMETOOLONG] = 78,
|
||||
#ifdef EOVERFLOW
|
||||
[EOVERFLOW] = 79,
|
||||
#endif
|
||||
#ifdef ELOOP
|
||||
[ELOOP] = 90,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int errno_mips(int err)
|
||||
{
|
||||
if (err < 0 || err >= ARRAY_SIZE(host_to_mips_errno)) {
|
||||
return EINVAL;
|
||||
} else if (host_to_mips_errno[err]) {
|
||||
return host_to_mips_errno[err];
|
||||
} else {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
static int copy_stat_to_target(CPUMIPSState *env, const struct stat *src,
|
||||
target_ulong vaddr)
|
||||
{
|
||||
hwaddr len = sizeof(struct UHIStat);
|
||||
UHIStat *dst = lock_user(VERIFY_WRITE, vaddr, len, 0);
|
||||
if (!dst) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
dst->uhi_st_dev = tswap16(src->st_dev);
|
||||
dst->uhi_st_ino = tswap16(src->st_ino);
|
||||
dst->uhi_st_mode = tswap32(src->st_mode);
|
||||
dst->uhi_st_nlink = tswap16(src->st_nlink);
|
||||
dst->uhi_st_uid = tswap16(src->st_uid);
|
||||
dst->uhi_st_gid = tswap16(src->st_gid);
|
||||
dst->uhi_st_rdev = tswap16(src->st_rdev);
|
||||
dst->uhi_st_size = tswap64(src->st_size);
|
||||
dst->uhi_st_atime = tswap64(src->st_atime);
|
||||
dst->uhi_st_mtime = tswap64(src->st_mtime);
|
||||
dst->uhi_st_ctime = tswap64(src->st_ctime);
|
||||
#ifdef _WIN32
|
||||
dst->uhi_st_blksize = 0;
|
||||
dst->uhi_st_blocks = 0;
|
||||
#else
|
||||
dst->uhi_st_blksize = tswap64(src->st_blksize);
|
||||
dst->uhi_st_blocks = tswap64(src->st_blocks);
|
||||
#endif
|
||||
unlock_user(dst, vaddr, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_open_flags(target_ulong target_flags)
|
||||
{
|
||||
int open_flags = 0;
|
||||
|
||||
if (target_flags & UHIOpen_RDWR) {
|
||||
open_flags |= O_RDWR;
|
||||
} else if (target_flags & UHIOpen_WRONLY) {
|
||||
open_flags |= O_WRONLY;
|
||||
} else {
|
||||
open_flags |= O_RDONLY;
|
||||
}
|
||||
|
||||
open_flags |= (target_flags & UHIOpen_APPEND) ? O_APPEND : 0;
|
||||
open_flags |= (target_flags & UHIOpen_CREAT) ? O_CREAT : 0;
|
||||
open_flags |= (target_flags & UHIOpen_TRUNC) ? O_TRUNC : 0;
|
||||
open_flags |= (target_flags & UHIOpen_EXCL) ? O_EXCL : 0;
|
||||
|
||||
return open_flags;
|
||||
}
|
||||
|
||||
static int write_to_file(CPUMIPSState *env, target_ulong fd, target_ulong vaddr,
|
||||
target_ulong len, target_ulong offset)
|
||||
{
|
||||
int num_of_bytes;
|
||||
void *dst = lock_user(VERIFY_READ, vaddr, len, 1);
|
||||
if (!dst) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (offset) {
|
||||
#ifdef _WIN32
|
||||
num_of_bytes = 0;
|
||||
#else
|
||||
num_of_bytes = pwrite(fd, dst, len, offset);
|
||||
#endif
|
||||
} else {
|
||||
num_of_bytes = write(fd, dst, len);
|
||||
}
|
||||
|
||||
unlock_user(dst, vaddr, 0);
|
||||
return num_of_bytes;
|
||||
}
|
||||
|
||||
static int read_from_file(CPUMIPSState *env, target_ulong fd,
|
||||
target_ulong vaddr, target_ulong len,
|
||||
target_ulong offset)
|
||||
{
|
||||
int num_of_bytes;
|
||||
void *dst = lock_user(VERIFY_WRITE, vaddr, len, 0);
|
||||
if (!dst) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (offset) {
|
||||
#ifdef _WIN32
|
||||
num_of_bytes = 0;
|
||||
#else
|
||||
num_of_bytes = pread(fd, dst, len, offset);
|
||||
#endif
|
||||
} else {
|
||||
num_of_bytes = read(fd, dst, len);
|
||||
}
|
||||
|
||||
unlock_user(dst, vaddr, len);
|
||||
return num_of_bytes;
|
||||
}
|
||||
|
||||
static int copy_argn_to_target(CPUMIPSState *env, int arg_num,
|
||||
target_ulong vaddr)
|
||||
{
|
||||
int strsize = strlen(semihosting_get_arg(arg_num)) + 1;
|
||||
char *dst = lock_user(VERIFY_WRITE, vaddr, strsize, 0);
|
||||
if (!dst) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy(dst, semihosting_get_arg(arg_num));
|
||||
|
||||
unlock_user(dst, vaddr, strsize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define GET_TARGET_STRING(p, addr) \
|
||||
do { \
|
||||
p = lock_user_string(addr); \
|
||||
if (!p) { \
|
||||
gpr[2] = -1; \
|
||||
gpr[3] = EFAULT; \
|
||||
goto uhi_done; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define FREE_TARGET_STRING(p, gpr) \
|
||||
do { \
|
||||
unlock_user(p, gpr, 0); \
|
||||
} while (0)
|
||||
|
||||
void helper_do_semihosting(CPUMIPSState *env)
|
||||
{
|
||||
target_ulong *gpr = env->active_tc.gpr;
|
||||
const UHIOp op = gpr[25];
|
||||
char *p, *p2;
|
||||
|
||||
switch (op) {
|
||||
case UHI_exit:
|
||||
qemu_log("UHI(%d): exit(%d)\n", op, (int)gpr[4]);
|
||||
exit(gpr[4]);
|
||||
case UHI_open:
|
||||
GET_TARGET_STRING(p, gpr[4]);
|
||||
if (!strcmp("/dev/stdin", p)) {
|
||||
gpr[2] = 0;
|
||||
} else if (!strcmp("/dev/stdout", p)) {
|
||||
gpr[2] = 1;
|
||||
} else if (!strcmp("/dev/stderr", p)) {
|
||||
gpr[2] = 2;
|
||||
} else {
|
||||
gpr[2] = open(p, get_open_flags(gpr[5]), gpr[6]);
|
||||
gpr[3] = errno_mips(errno);
|
||||
}
|
||||
FREE_TARGET_STRING(p, gpr[4]);
|
||||
break;
|
||||
case UHI_close:
|
||||
if (gpr[4] < 3) {
|
||||
/* ignore closing stdin/stdout/stderr */
|
||||
gpr[2] = 0;
|
||||
goto uhi_done;
|
||||
}
|
||||
gpr[2] = close(gpr[4]);
|
||||
gpr[3] = errno_mips(errno);
|
||||
break;
|
||||
case UHI_read:
|
||||
gpr[2] = read_from_file(env, gpr[4], gpr[5], gpr[6], 0);
|
||||
gpr[3] = errno_mips(errno);
|
||||
break;
|
||||
case UHI_write:
|
||||
gpr[2] = write_to_file(env, gpr[4], gpr[5], gpr[6], 0);
|
||||
gpr[3] = errno_mips(errno);
|
||||
break;
|
||||
case UHI_lseek:
|
||||
gpr[2] = lseek(gpr[4], gpr[5], gpr[6]);
|
||||
gpr[3] = errno_mips(errno);
|
||||
break;
|
||||
case UHI_unlink:
|
||||
GET_TARGET_STRING(p, gpr[4]);
|
||||
gpr[2] = remove(p);
|
||||
gpr[3] = errno_mips(errno);
|
||||
FREE_TARGET_STRING(p, gpr[4]);
|
||||
break;
|
||||
case UHI_fstat:
|
||||
{
|
||||
struct stat sbuf;
|
||||
memset(&sbuf, 0, sizeof(sbuf));
|
||||
gpr[2] = fstat(gpr[4], &sbuf);
|
||||
gpr[3] = errno_mips(errno);
|
||||
if (gpr[2]) {
|
||||
goto uhi_done;
|
||||
}
|
||||
gpr[2] = copy_stat_to_target(env, &sbuf, gpr[5]);
|
||||
gpr[3] = errno_mips(errno);
|
||||
}
|
||||
break;
|
||||
case UHI_argc:
|
||||
gpr[2] = semihosting_get_argc();
|
||||
break;
|
||||
case UHI_argnlen:
|
||||
if (gpr[4] >= semihosting_get_argc()) {
|
||||
gpr[2] = -1;
|
||||
goto uhi_done;
|
||||
}
|
||||
gpr[2] = strlen(semihosting_get_arg(gpr[4]));
|
||||
break;
|
||||
case UHI_argn:
|
||||
if (gpr[4] >= semihosting_get_argc()) {
|
||||
gpr[2] = -1;
|
||||
goto uhi_done;
|
||||
}
|
||||
gpr[2] = copy_argn_to_target(env, gpr[4], gpr[5]);
|
||||
break;
|
||||
case UHI_plog:
|
||||
GET_TARGET_STRING(p, gpr[4]);
|
||||
p2 = strstr(p, "%d");
|
||||
if (p2) {
|
||||
int char_num = p2 - p;
|
||||
char *buf = g_malloc(char_num + 1);
|
||||
strncpy(buf, p, char_num);
|
||||
buf[char_num] = '\0';
|
||||
gpr[2] = printf("%s%d%s", buf, (int)gpr[5], p2 + 2);
|
||||
g_free(buf);
|
||||
} else {
|
||||
gpr[2] = printf("%s", p);
|
||||
}
|
||||
FREE_TARGET_STRING(p, gpr[4]);
|
||||
break;
|
||||
case UHI_assert:
|
||||
GET_TARGET_STRING(p, gpr[4]);
|
||||
GET_TARGET_STRING(p2, gpr[5]);
|
||||
printf("assertion '");
|
||||
printf("\"%s\"", p);
|
||||
printf("': file \"%s\", line %d\n", p2, (int)gpr[6]);
|
||||
FREE_TARGET_STRING(p2, gpr[5]);
|
||||
FREE_TARGET_STRING(p, gpr[4]);
|
||||
abort();
|
||||
break;
|
||||
case UHI_pread:
|
||||
gpr[2] = read_from_file(env, gpr[4], gpr[5], gpr[6], gpr[7]);
|
||||
gpr[3] = errno_mips(errno);
|
||||
break;
|
||||
case UHI_pwrite:
|
||||
gpr[2] = write_to_file(env, gpr[4], gpr[5], gpr[6], gpr[7]);
|
||||
gpr[3] = errno_mips(errno);
|
||||
break;
|
||||
#ifndef _WIN32
|
||||
case UHI_link:
|
||||
GET_TARGET_STRING(p, gpr[4]);
|
||||
GET_TARGET_STRING(p2, gpr[5]);
|
||||
gpr[2] = link(p, p2);
|
||||
gpr[3] = errno_mips(errno);
|
||||
FREE_TARGET_STRING(p2, gpr[5]);
|
||||
FREE_TARGET_STRING(p, gpr[4]);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
fprintf(stderr, "Unknown UHI operation %d\n", op);
|
||||
abort();
|
||||
}
|
||||
uhi_done:
|
||||
return;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -424,6 +424,43 @@ static const mips_def_t mips_defs[] =
|
||||
.insn_flags = CPU_MIPS32R5 | ASE_MIPS16 | ASE_MSA,
|
||||
.mmu_type = MMU_TYPE_R4000,
|
||||
},
|
||||
{
|
||||
/* A generic CPU supporting MIPS32 Release 6 ISA.
|
||||
FIXME: Support IEEE 754-2008 FP.
|
||||
Eventually this should be replaced by a real CPU model. */
|
||||
.name = "mips32r6-generic",
|
||||
.CP0_PRid = 0x00010000,
|
||||
.CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AR) |
|
||||
(MMU_TYPE_R4000 << CP0C0_MT),
|
||||
.CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (31 << CP0C1_MMU) |
|
||||
(2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) |
|
||||
(2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) |
|
||||
(0 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
|
||||
.CP0_Config2 = MIPS_CONFIG2,
|
||||
.CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_BP) | (1 << CP0C3_BI) |
|
||||
(2 << CP0C3_ISA) | (1 << CP0C3_ULRI) |
|
||||
(1 << CP0C3_RXI) | (1U << CP0C3_M),
|
||||
.CP0_Config4 = MIPS_CONFIG4 | (0xfc << CP0C4_KScrExist) |
|
||||
(3 << CP0C4_IE) | (1U << CP0C4_M),
|
||||
.CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_LLB),
|
||||
.CP0_Config5_rw_bitmask = (1 << CP0C5_SBRI) | (1 << CP0C5_FRE) |
|
||||
(1 << CP0C5_UFE),
|
||||
.CP0_LLAddr_rw_bitmask = 0,
|
||||
.CP0_LLAddr_shift = 0,
|
||||
.SYNCI_Step = 32,
|
||||
.CCRes = 2,
|
||||
.CP0_Status_rw_bitmask = 0x3058FF1F,
|
||||
.CP0_PageGrain = (1 << CP0PG_IEC) | (1 << CP0PG_XIE) |
|
||||
(1U << CP0PG_RIE),
|
||||
.CP0_PageGrain_rw_bitmask = 0,
|
||||
.CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_F64) | (1 << FCR0_L) |
|
||||
(1 << FCR0_W) | (1 << FCR0_D) | (1 << FCR0_S) |
|
||||
(0x00 << FCR0_PRID) | (0x0 << FCR0_REV),
|
||||
.SEGBITS = 32,
|
||||
.PABITS = 32,
|
||||
.insn_flags = CPU_MIPS32R6 | ASE_MICROMIPS,
|
||||
.mmu_type = MMU_TYPE_R4000,
|
||||
},
|
||||
#if defined(TARGET_MIPS64)
|
||||
{
|
||||
.name = "R4000",
|
||||
|
Loading…
x
Reference in New Issue
Block a user