MIPS queue August 2018 v6
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJbgCm7AAoJENSXKoln91plhJYH/jRqbCaUd04nGuyjOaYUajTL brz3JD0XN2jD6NnDYUpuiNzawSojNzSklMA0u9AJiG+cpNK+gqW4fX+CYeX7ApjK 99+SXSejxnK3IJUNblQDD/hdCv9Dc1r12R7c80lm+aqJwi4C8hfULTbfrse/QdyA KIHKl+c3uaWTPG2qC3mpPW/QS+IRPgRRwF/7GILuiagNmMcXyuMd2fQuePnf1rvD ztTdtNJ0zfdFK1jlLa7D9Xe36RpS1uBinF429dNwXWM/+i1shvxc3Enzb4qEQNYe ZeVxTomP/nO1elLZYdVUwdQYr6vmnvb1/mtTT6nq0NvHeLGjMZMqOBWGuAtdXoo= =a8Jv -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/amarkovic/tags/mips-queue-aug-2018' into staging MIPS queue August 2018 v6 # gpg: Signature made Fri 24 Aug 2018 16:52:27 BST # gpg: using RSA key D4972A8967F75A65 # gpg: Good signature from "Aleksandar Markovic <amarkovic@wavecomp.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: 8526 FBF1 5DA3 811F 4A01 DD75 D497 2A89 67F7 5A65 * remotes/amarkovic/tags/mips-queue-aug-2018: (45 commits) target/mips: Add definition of nanoMIPS I7200 CPU mips_malta: Fix semihosting argument passing for nanoMIPS bare metal mips_malta: Add setting up GT64120 BARs to the nanoMIPS bootloader mips_malta: Add basic nanoMIPS boot code for Malta board elf: Don't check FCR31_NAN2008 bit for nanoMIPS elf: On elf loading, treat both EM_MIPS and EM_NANOMIPS as legal for MIPS elf: Relax MIPS' elf_check_arch() to accept EM_NANOMIPS too elf: Add EM_NANOMIPS value as a valid one for e_machine field target/mips: Fix ERET/ERETNC behavior related to ADEL exception target/mips: Add updating BadInstr and BadInstrX for nanoMIPS target/mips: Add availability control via bit NMS target/mips: Add emulation of DSP ASE for nanoMIPS - part 6 target/mips: Add emulation of DSP ASE for nanoMIPS - part 5 target/mips: Add emulation of DSP ASE for nanoMIPS - part 4 target/mips: Add emulation of DSP ASE for nanoMIPS - part 3 target/mips: Add emulation of DSP ASE for nanoMIPS - part 2 target/mips: Add emulation of DSP ASE for nanoMIPS - part 1 target/mips: Implement MT ASE support for nanoMIPS target/mips: Fix pre-nanoMIPS MT ASE instructions availability control target/mips: Add emulation of nanoMIPS 32-bit branch instructions ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
e2e6fa6793
@ -599,6 +599,208 @@ static void network_init(PCIBus *pci_bus)
|
||||
}
|
||||
}
|
||||
|
||||
static void write_bootloader_nanomips(uint8_t *base, int64_t run_addr,
|
||||
int64_t kernel_entry)
|
||||
{
|
||||
uint16_t *p;
|
||||
|
||||
/* Small bootloader */
|
||||
p = (uint16_t *)base;
|
||||
|
||||
#define NM_HI1(VAL) (((VAL) >> 16) & 0x1f)
|
||||
#define NM_HI2(VAL) \
|
||||
(((VAL) & 0xf000) | (((VAL) >> 19) & 0xffc) | (((VAL) >> 31) & 0x1))
|
||||
#define NM_LO(VAL) ((VAL) & 0xfff)
|
||||
|
||||
stw_p(p++, 0x2800); stw_p(p++, 0x001c);
|
||||
/* bc to_here */
|
||||
stw_p(p++, 0x8000); stw_p(p++, 0xc000);
|
||||
/* nop */
|
||||
stw_p(p++, 0x8000); stw_p(p++, 0xc000);
|
||||
/* nop */
|
||||
stw_p(p++, 0x8000); stw_p(p++, 0xc000);
|
||||
/* nop */
|
||||
stw_p(p++, 0x8000); stw_p(p++, 0xc000);
|
||||
/* nop */
|
||||
stw_p(p++, 0x8000); stw_p(p++, 0xc000);
|
||||
/* nop */
|
||||
stw_p(p++, 0x8000); stw_p(p++, 0xc000);
|
||||
/* nop */
|
||||
stw_p(p++, 0x8000); stw_p(p++, 0xc000);
|
||||
/* nop */
|
||||
|
||||
/* to_here: */
|
||||
if (semihosting_get_argc()) {
|
||||
/* Preserve a0 content as arguments have been passed */
|
||||
stw_p(p++, 0x8000); stw_p(p++, 0xc000);
|
||||
/* nop */
|
||||
} else {
|
||||
stw_p(p++, 0x0080); stw_p(p++, 0x0002);
|
||||
/* li a0,2 */
|
||||
}
|
||||
|
||||
stw_p(p++, 0xe3a0 | NM_HI1(ENVP_ADDR - 64));
|
||||
|
||||
stw_p(p++, NM_HI2(ENVP_ADDR - 64));
|
||||
/* lui sp,%hi(ENVP_ADDR - 64) */
|
||||
|
||||
stw_p(p++, 0x83bd); stw_p(p++, NM_LO(ENVP_ADDR - 64));
|
||||
/* ori sp,sp,%lo(ENVP_ADDR - 64) */
|
||||
|
||||
stw_p(p++, 0xe0a0 | NM_HI1(ENVP_ADDR));
|
||||
|
||||
stw_p(p++, NM_HI2(ENVP_ADDR));
|
||||
/* lui a1,%hi(ENVP_ADDR) */
|
||||
|
||||
stw_p(p++, 0x80a5); stw_p(p++, NM_LO(ENVP_ADDR));
|
||||
/* ori a1,a1,%lo(ENVP_ADDR) */
|
||||
|
||||
stw_p(p++, 0xe0c0 | NM_HI1(ENVP_ADDR + 8));
|
||||
|
||||
stw_p(p++, NM_HI2(ENVP_ADDR + 8));
|
||||
/* lui a2,%hi(ENVP_ADDR + 8) */
|
||||
|
||||
stw_p(p++, 0x80c6); stw_p(p++, NM_LO(ENVP_ADDR + 8));
|
||||
/* ori a2,a2,%lo(ENVP_ADDR + 8) */
|
||||
|
||||
stw_p(p++, 0xe0e0 | NM_HI1(loaderparams.ram_low_size));
|
||||
|
||||
stw_p(p++, NM_HI2(loaderparams.ram_low_size));
|
||||
/* lui a3,%hi(loaderparams.ram_low_size) */
|
||||
|
||||
stw_p(p++, 0x80e7); stw_p(p++, NM_LO(loaderparams.ram_low_size));
|
||||
/* ori a3,a3,%lo(loaderparams.ram_low_size) */
|
||||
|
||||
/*
|
||||
* Load BAR registers as done by YAMON:
|
||||
*
|
||||
* - set up PCI0 I/O BARs from 0x18000000 to 0x181fffff
|
||||
* - set up PCI0 MEM0 at 0x10000000, size 0x8000000
|
||||
* - set up PCI0 MEM1 at 0x18200000, size 0xbe00000
|
||||
*
|
||||
*/
|
||||
stw_p(p++, 0xe040); stw_p(p++, 0x0681);
|
||||
/* lui t1, %hi(0xb4000000) */
|
||||
|
||||
#ifdef TARGET_WORDS_BIGENDIAN
|
||||
|
||||
stw_p(p++, 0xe020); stw_p(p++, 0x0be1);
|
||||
/* lui t0, %hi(0xdf000000) */
|
||||
|
||||
/* 0x68 corresponds to GT_ISD (from hw/mips/gt64xxx_pci.c) */
|
||||
stw_p(p++, 0x8422); stw_p(p++, 0x9068);
|
||||
/* sw t0, 0x68(t1) */
|
||||
|
||||
stw_p(p++, 0xe040); stw_p(p++, 0x077d);
|
||||
/* lui t1, %hi(0xbbe00000) */
|
||||
|
||||
stw_p(p++, 0xe020); stw_p(p++, 0x0801);
|
||||
/* lui t0, %hi(0xc0000000) */
|
||||
|
||||
/* 0x48 corresponds to GT_PCI0IOLD */
|
||||
stw_p(p++, 0x8422); stw_p(p++, 0x9048);
|
||||
/* sw t0, 0x48(t1) */
|
||||
|
||||
stw_p(p++, 0xe020); stw_p(p++, 0x0800);
|
||||
/* lui t0, %hi(0x40000000) */
|
||||
|
||||
/* 0x50 corresponds to GT_PCI0IOHD */
|
||||
stw_p(p++, 0x8422); stw_p(p++, 0x9050);
|
||||
/* sw t0, 0x50(t1) */
|
||||
|
||||
stw_p(p++, 0xe020); stw_p(p++, 0x0001);
|
||||
/* lui t0, %hi(0x80000000) */
|
||||
|
||||
/* 0x58 corresponds to GT_PCI0M0LD */
|
||||
stw_p(p++, 0x8422); stw_p(p++, 0x9058);
|
||||
/* sw t0, 0x58(t1) */
|
||||
|
||||
stw_p(p++, 0xe020); stw_p(p++, 0x07e0);
|
||||
/* lui t0, %hi(0x3f000000) */
|
||||
|
||||
/* 0x60 corresponds to GT_PCI0M0HD */
|
||||
stw_p(p++, 0x8422); stw_p(p++, 0x9060);
|
||||
/* sw t0, 0x60(t1) */
|
||||
|
||||
stw_p(p++, 0xe020); stw_p(p++, 0x0821);
|
||||
/* lui t0, %hi(0xc1000000) */
|
||||
|
||||
/* 0x80 corresponds to GT_PCI0M1LD */
|
||||
stw_p(p++, 0x8422); stw_p(p++, 0x9080);
|
||||
/* sw t0, 0x80(t1) */
|
||||
|
||||
stw_p(p++, 0xe020); stw_p(p++, 0x0bc0);
|
||||
/* lui t0, %hi(0x5e000000) */
|
||||
|
||||
#else
|
||||
|
||||
stw_p(p++, 0x0020); stw_p(p++, 0x00df);
|
||||
/* addiu[32] t0, $0, 0xdf */
|
||||
|
||||
/* 0x68 corresponds to GT_ISD */
|
||||
stw_p(p++, 0x8422); stw_p(p++, 0x9068);
|
||||
/* sw t0, 0x68(t1) */
|
||||
|
||||
/* Use kseg2 remapped address 0x1be00000 */
|
||||
stw_p(p++, 0xe040); stw_p(p++, 0x077d);
|
||||
/* lui t1, %hi(0xbbe00000) */
|
||||
|
||||
stw_p(p++, 0x0020); stw_p(p++, 0x00c0);
|
||||
/* addiu[32] t0, $0, 0xc0 */
|
||||
|
||||
/* 0x48 corresponds to GT_PCI0IOLD */
|
||||
stw_p(p++, 0x8422); stw_p(p++, 0x9048);
|
||||
/* sw t0, 0x48(t1) */
|
||||
|
||||
stw_p(p++, 0x0020); stw_p(p++, 0x0040);
|
||||
/* addiu[32] t0, $0, 0x40 */
|
||||
|
||||
/* 0x50 corresponds to GT_PCI0IOHD */
|
||||
stw_p(p++, 0x8422); stw_p(p++, 0x9050);
|
||||
/* sw t0, 0x50(t1) */
|
||||
|
||||
stw_p(p++, 0x0020); stw_p(p++, 0x0080);
|
||||
/* addiu[32] t0, $0, 0x80 */
|
||||
|
||||
/* 0x58 corresponds to GT_PCI0M0LD */
|
||||
stw_p(p++, 0x8422); stw_p(p++, 0x9058);
|
||||
/* sw t0, 0x58(t1) */
|
||||
|
||||
stw_p(p++, 0x0020); stw_p(p++, 0x003f);
|
||||
/* addiu[32] t0, $0, 0x3f */
|
||||
|
||||
/* 0x60 corresponds to GT_PCI0M0HD */
|
||||
stw_p(p++, 0x8422); stw_p(p++, 0x9060);
|
||||
/* sw t0, 0x60(t1) */
|
||||
|
||||
stw_p(p++, 0x0020); stw_p(p++, 0x00c1);
|
||||
/* addiu[32] t0, $0, 0xc1 */
|
||||
|
||||
/* 0x80 corresponds to GT_PCI0M1LD */
|
||||
stw_p(p++, 0x8422); stw_p(p++, 0x9080);
|
||||
/* sw t0, 0x80(t1) */
|
||||
|
||||
stw_p(p++, 0x0020); stw_p(p++, 0x005e);
|
||||
/* addiu[32] t0, $0, 0x5e */
|
||||
|
||||
#endif
|
||||
|
||||
/* 0x88 corresponds to GT_PCI0M1HD */
|
||||
stw_p(p++, 0x8422); stw_p(p++, 0x9088);
|
||||
/* sw t0, 0x88(t1) */
|
||||
|
||||
stw_p(p++, 0xe320 | NM_HI1(kernel_entry));
|
||||
|
||||
stw_p(p++, NM_HI2(kernel_entry));
|
||||
/* lui t9,%hi(kernel_entry) */
|
||||
|
||||
stw_p(p++, 0x8339); stw_p(p++, NM_LO(kernel_entry));
|
||||
/* ori t9,t9,%lo(kernel_entry) */
|
||||
|
||||
stw_p(p++, 0x4bf9); stw_p(p++, 0x0000);
|
||||
/* jalrc t8 */
|
||||
}
|
||||
|
||||
/* ROM and pseudo bootloader
|
||||
|
||||
The following code implements a very very simple bootloader. It first
|
||||
@ -620,7 +822,6 @@ static void network_init(PCIBus *pci_bus)
|
||||
a2 - 32-bit address of the environment variables table
|
||||
a3 - RAM size in bytes
|
||||
*/
|
||||
|
||||
static void write_bootloader(uint8_t *base, int64_t run_addr,
|
||||
int64_t kernel_entry)
|
||||
{
|
||||
@ -1096,8 +1297,13 @@ void mips_malta_init(MachineState *machine)
|
||||
loaderparams.initrd_filename = initrd_filename;
|
||||
kernel_entry = load_kernel();
|
||||
|
||||
write_bootloader(memory_region_get_ram_ptr(bios),
|
||||
bootloader_run_addr, kernel_entry);
|
||||
if (!cpu_supports_isa(machine->cpu_type, ISA_NANOMIPS32)) {
|
||||
write_bootloader(memory_region_get_ram_ptr(bios),
|
||||
bootloader_run_addr, kernel_entry);
|
||||
} else {
|
||||
write_bootloader_nanomips(memory_region_get_ram_ptr(bios),
|
||||
bootloader_run_addr, kernel_entry);
|
||||
}
|
||||
if (kvm_enabled()) {
|
||||
/* Write the bootloader code @ the end of RAM, 1MB reserved */
|
||||
write_bootloader(memory_region_get_ram_ptr(ram_low_preio) +
|
||||
|
@ -143,6 +143,8 @@ typedef int64_t Elf64_Sxword;
|
||||
|
||||
#define EM_RISCV 243 /* RISC-V */
|
||||
|
||||
#define EM_NANOMIPS 249 /* Wave Computing nanoMIPS */
|
||||
|
||||
/*
|
||||
* This is an interim value that we will use until the committee comes
|
||||
* up with a final number.
|
||||
|
@ -327,6 +327,14 @@ static int glue(load_elf, SZ)(const char *name, int fd,
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EM_MIPS:
|
||||
case EM_NANOMIPS:
|
||||
if ((ehdr.e_machine != EM_MIPS) &&
|
||||
(ehdr.e_machine != EM_NANOMIPS)) {
|
||||
ret = ELF_LOAD_WRONG_ARCH;
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (elf_machine != ehdr.e_machine) {
|
||||
ret = ELF_LOAD_WRONG_ARCH;
|
||||
|
@ -853,6 +853,8 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUPPCState *en
|
||||
#endif
|
||||
#define ELF_ARCH EM_MIPS
|
||||
|
||||
#define elf_check_arch(x) ((x) == EM_MIPS || (x) == EM_NANOMIPS)
|
||||
|
||||
static inline void init_thread(struct target_pt_regs *regs,
|
||||
struct image_info *infop)
|
||||
{
|
||||
|
@ -397,10 +397,13 @@ static int do_store_exclusive(CPUMIPSState *env)
|
||||
target_ulong addr;
|
||||
target_ulong page_addr;
|
||||
target_ulong val;
|
||||
uint32_t val_wp = 0;
|
||||
uint32_t llnewval_wp = 0;
|
||||
int flags;
|
||||
int segv = 0;
|
||||
int reg;
|
||||
int d;
|
||||
int wp;
|
||||
|
||||
addr = env->lladdr;
|
||||
page_addr = addr & TARGET_PAGE_MASK;
|
||||
@ -412,19 +415,31 @@ static int do_store_exclusive(CPUMIPSState *env)
|
||||
} else {
|
||||
reg = env->llreg & 0x1f;
|
||||
d = (env->llreg & 0x20) != 0;
|
||||
if (d) {
|
||||
segv = get_user_s64(val, addr);
|
||||
wp = (env->llreg & 0x40) != 0;
|
||||
if (!wp) {
|
||||
if (d) {
|
||||
segv = get_user_s64(val, addr);
|
||||
} else {
|
||||
segv = get_user_s32(val, addr);
|
||||
}
|
||||
} else {
|
||||
segv = get_user_s32(val, addr);
|
||||
segv |= get_user_s32(val_wp, addr);
|
||||
llnewval_wp = env->llnewval_wp;
|
||||
}
|
||||
if (!segv) {
|
||||
if (val != env->llval) {
|
||||
if (val != env->llval && val_wp == llnewval_wp) {
|
||||
env->active_tc.gpr[reg] = 0;
|
||||
} else {
|
||||
if (d) {
|
||||
segv = put_user_u64(env->llnewval, addr);
|
||||
if (!wp) {
|
||||
if (d) {
|
||||
segv = put_user_u64(env->llnewval, addr);
|
||||
} else {
|
||||
segv = put_user_u32(env->llnewval, addr);
|
||||
}
|
||||
} else {
|
||||
segv = put_user_u32(env->llnewval, addr);
|
||||
segv |= put_user_u32(env->llnewval_wp, addr + 4);
|
||||
}
|
||||
if (!segv) {
|
||||
env->active_tc.gpr[reg] = 1;
|
||||
@ -732,6 +747,9 @@ void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
|
||||
if (regs->cp0_epc & 1) {
|
||||
env->hflags |= MIPS_HFLAG_M16;
|
||||
}
|
||||
if (env->insn_flags & ISA_NANOMIPS32) {
|
||||
return;
|
||||
}
|
||||
if (((info->elf_flags & EF_MIPS_NAN2008) != 0) !=
|
||||
((env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) != 0)) {
|
||||
if ((env->active_fpu.fcr31_rw_bitmask &
|
||||
|
@ -506,6 +506,8 @@ struct CPUMIPSState {
|
||||
uint64_t lladdr;
|
||||
target_ulong llval;
|
||||
target_ulong llnewval;
|
||||
uint64_t llval_wp;
|
||||
uint32_t llnewval_wp;
|
||||
target_ulong llreg;
|
||||
uint64_t CP0_LLAddr_rw_bitmask;
|
||||
int CP0_LLAddr_shift;
|
||||
|
@ -682,6 +682,22 @@ static void set_hflags_for_handler (CPUMIPSState *env)
|
||||
|
||||
static inline void set_badinstr_registers(CPUMIPSState *env)
|
||||
{
|
||||
if (env->insn_flags & ISA_NANOMIPS32) {
|
||||
if (env->CP0_Config3 & (1 << CP0C3_BI)) {
|
||||
uint32_t instr = (cpu_lduw_code(env, env->active_tc.PC)) << 16;
|
||||
if ((instr & 0x10000000) == 0) {
|
||||
instr |= cpu_lduw_code(env, env->active_tc.PC + 2);
|
||||
}
|
||||
env->CP0_BadInstr = instr;
|
||||
|
||||
if ((instr & 0xFC000000) == 0x60000000) {
|
||||
instr = cpu_lduw_code(env, env->active_tc.PC + 4) << 16;
|
||||
env->CP0_BadInstrX = instr;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (env->hflags & MIPS_HFLAG_M16) {
|
||||
/* TODO: add BadInstr support for microMIPS */
|
||||
return;
|
||||
|
@ -40,6 +40,8 @@ DEF_HELPER_FLAGS_1(bitswap, TCG_CALL_NO_RWG_SE, tl, tl)
|
||||
DEF_HELPER_FLAGS_1(dbitswap, TCG_CALL_NO_RWG_SE, tl, tl)
|
||||
#endif
|
||||
|
||||
DEF_HELPER_FLAGS_4(rotx, TCG_CALL_NO_RWG_SE, tl, tl, i32, i32, i32)
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
/* CP0 helpers */
|
||||
DEF_HELPER_1(mfc0_mvpcontrol, tl, env)
|
||||
|
@ -39,6 +39,7 @@
|
||||
#define ISA_MIPS64R5 0x00001000
|
||||
#define ISA_MIPS32R6 0x00002000
|
||||
#define ISA_MIPS64R6 0x00004000
|
||||
#define ISA_NANOMIPS32 0x00008000
|
||||
|
||||
/* MIPS ASEs. */
|
||||
#define ASE_MIPS16 0x00010000
|
||||
@ -87,6 +88,9 @@
|
||||
#define CPU_MIPS32R6 (CPU_MIPS32R5 | ISA_MIPS32R6)
|
||||
#define CPU_MIPS64R6 (CPU_MIPS64R5 | CPU_MIPS32R6 | ISA_MIPS64R6)
|
||||
|
||||
/* Wave Computing: "nanoMIPS" */
|
||||
#define CPU_NANOMIPS32 (CPU_MIPS32R6 | ISA_NANOMIPS32)
|
||||
|
||||
/* Strictly follow the architecture standard:
|
||||
- Disallow "special" instruction handling for PMON/SPIM.
|
||||
Note that we still maintain Count/Compare to match the host clock. */
|
||||
|
@ -249,6 +249,100 @@ target_ulong helper_bitswap(target_ulong rt)
|
||||
return (int32_t)bitswap(rt);
|
||||
}
|
||||
|
||||
target_ulong helper_rotx(target_ulong rs, uint32_t shift, uint32_t shiftx,
|
||||
uint32_t stripe)
|
||||
{
|
||||
int i;
|
||||
uint64_t tmp0 = ((uint64_t)rs) << 32 | ((uint64_t)rs & 0xffffffff);
|
||||
uint64_t tmp1 = tmp0;
|
||||
for (i = 0; i <= 46; i++) {
|
||||
int s;
|
||||
if (i & 0x8) {
|
||||
s = shift;
|
||||
} else {
|
||||
s = shiftx;
|
||||
}
|
||||
|
||||
if (stripe != 0 && !(i & 0x4)) {
|
||||
s = ~s;
|
||||
}
|
||||
if (s & 0x10) {
|
||||
if (tmp0 & (1LL << (i + 16))) {
|
||||
tmp1 |= 1LL << i;
|
||||
} else {
|
||||
tmp1 &= ~(1LL << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t tmp2 = tmp1;
|
||||
for (i = 0; i <= 38; i++) {
|
||||
int s;
|
||||
if (i & 0x4) {
|
||||
s = shift;
|
||||
} else {
|
||||
s = shiftx;
|
||||
}
|
||||
|
||||
if (s & 0x8) {
|
||||
if (tmp1 & (1LL << (i + 8))) {
|
||||
tmp2 |= 1LL << i;
|
||||
} else {
|
||||
tmp2 &= ~(1LL << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t tmp3 = tmp2;
|
||||
for (i = 0; i <= 34; i++) {
|
||||
int s;
|
||||
if (i & 0x2) {
|
||||
s = shift;
|
||||
} else {
|
||||
s = shiftx;
|
||||
}
|
||||
if (s & 0x4) {
|
||||
if (tmp2 & (1LL << (i + 4))) {
|
||||
tmp3 |= 1LL << i;
|
||||
} else {
|
||||
tmp3 &= ~(1LL << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t tmp4 = tmp3;
|
||||
for (i = 0; i <= 32; i++) {
|
||||
int s;
|
||||
if (i & 0x1) {
|
||||
s = shift;
|
||||
} else {
|
||||
s = shiftx;
|
||||
}
|
||||
if (s & 0x2) {
|
||||
if (tmp3 & (1LL << (i + 2))) {
|
||||
tmp4 |= 1LL << i;
|
||||
} else {
|
||||
tmp4 &= ~(1LL << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t tmp5 = tmp4;
|
||||
for (i = 0; i <= 31; i++) {
|
||||
int s;
|
||||
s = shift;
|
||||
if (s & 0x1) {
|
||||
if (tmp4 & (1LL << (i + 1))) {
|
||||
tmp5 |= 1LL << i;
|
||||
} else {
|
||||
tmp5 &= ~(1LL << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (int64_t)(int32_t)(uint32_t)tmp5;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
|
||||
static inline hwaddr do_translate_address(CPUMIPSState *env,
|
||||
@ -2333,10 +2427,12 @@ void helper_eretnc(CPUMIPSState *env)
|
||||
void helper_deret(CPUMIPSState *env)
|
||||
{
|
||||
debug_pre_eret(env);
|
||||
set_pc(env, env->CP0_DEPC);
|
||||
|
||||
env->hflags &= ~MIPS_HFLAG_DM;
|
||||
compute_hflags(env);
|
||||
|
||||
set_pc(env, env->CP0_DEPC);
|
||||
|
||||
debug_post_eret(env);
|
||||
}
|
||||
#endif /* !CONFIG_USER_ONLY */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -449,6 +449,45 @@ const mips_def_t mips_defs[] =
|
||||
.insn_flags = CPU_MIPS32R6 | ASE_MICROMIPS,
|
||||
.mmu_type = MMU_TYPE_R4000,
|
||||
},
|
||||
{
|
||||
.name = "I7200",
|
||||
.CP0_PRid = 0x00010000,
|
||||
.CP0_Config0 = MIPS_CONFIG0 | (1 << CP0C0_MM) | (0x2 << CP0C0_AR) |
|
||||
(MMU_TYPE_R4000 << CP0C0_MT),
|
||||
.CP0_Config1 = (1U << CP0C1_M) | (15 << CP0C1_MMU) | (2 << CP0C1_IS) |
|
||||
(4 << CP0C1_IL) | (3 << CP0C1_IA) | (2 << CP0C1_DS) |
|
||||
(4 << CP0C1_DL) | (3 << CP0C1_DA) | (1 << CP0C1_PC) |
|
||||
(1 << CP0C1_EP),
|
||||
.CP0_Config2 = MIPS_CONFIG2,
|
||||
.CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | (1 << CP0C3_CMGCR) |
|
||||
(1 << CP0C3_BI) | (1 << CP0C3_SC) | (3 << CP0C3_MMAR) |
|
||||
(1 << CP0C3_ISA_ON_EXC) | (1 << CP0C3_ISA) |
|
||||
(1 << CP0C3_ULRI) | (1 << CP0C3_RXI) |
|
||||
(1 << CP0C3_DSP2P) | (1 << CP0C3_DSPP) |
|
||||
(1 << CP0C3_CTXTC) | (1 << CP0C3_VInt) |
|
||||
(1 << CP0C3_CDMM) | (1 << CP0C3_MT) | (1 << CP0C3_TL),
|
||||
.CP0_Config4 = MIPS_CONFIG4 | (0xfc << CP0C4_KScrExist) |
|
||||
(2 << CP0C4_IE) | (1U << CP0C4_M),
|
||||
.CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_MVH) | (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 = 0x3158FF1F,
|
||||
.CP0_PageGrain = (1 << CP0PG_IEC) | (1 << CP0PG_XIE) |
|
||||
(1U << CP0PG_RIE),
|
||||
.CP0_PageGrain_rw_bitmask = 0,
|
||||
.CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_HAS2008) | (1 << FCR0_F64) |
|
||||
(1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) |
|
||||
(1 << FCR0_S) | (0x02 << FCR0_PRID) | (0x0 << FCR0_REV),
|
||||
.CP1_fcr31 = (1 << FCR31_ABS2008) | (1 << FCR31_NAN2008),
|
||||
.SEGBITS = 32,
|
||||
.PABITS = 32,
|
||||
.insn_flags = CPU_NANOMIPS32 | ASE_DSP | ASE_DSPR2 | ASE_MT,
|
||||
.mmu_type = MMU_TYPE_R4000,
|
||||
},
|
||||
#if defined(TARGET_MIPS64)
|
||||
{
|
||||
.name = "R4000",
|
||||
|
Loading…
Reference in New Issue
Block a user