From aff2bc6dc6d839caf6df0900437cc2cc9e180605 Mon Sep 17 00:00:00 2001 From: Yongbok Kim Date: Fri, 10 Jul 2015 12:10:52 +0100 Subject: target-mips: update mips32r5-generic into P5600 As full specification of P5600 is available, mips32r5-generic should be renamed to P5600 and corrected as its intention. Correct PRid and detail of configuration. Features which are not currently supported are described as FIXME. Fix Config.MM bit location Signed-off-by: Yongbok Kim [leon.alrae@imgtec.com: correct cache line sizes and LLAddr shift] Signed-off-by: Leon Alrae --- target-mips/cpu.h | 2 +- target-mips/translate_init.c | 53 ++++++++++++++++++++++++-------------------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 075c561c81..c91883d5e1 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -395,7 +395,7 @@ struct CPUMIPSState { #define CP0C0_K23 28 #define CP0C0_KU 25 #define CP0C0_MDU 20 -#define CP0C0_MM 17 +#define CP0C0_MM 18 #define CP0C0_BM 16 #define CP0C0_BE 15 #define CP0C0_AT 13 diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c index 9304e746b4..1b45884e9b 100644 --- a/target-mips/translate_init.c +++ b/target-mips/translate_init.c @@ -389,39 +389,44 @@ static const mips_def_t mips_defs[] = .mmu_type = MMU_TYPE_R4000, }, { - /* A generic CPU providing MIPS32 Release 5 features. - FIXME: Eventually this should be replaced by a real CPU model. */ - .name = "mips32r5-generic", - .CP0_PRid = 0x00019700, - .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | + /* FIXME: + * Config3: CMGCR, SC, PW, VZ, CTXTC, CDMM, TL + * Config4: MMUExtDef + * Config5: EVA, MRP + * FIR(FCR0): Has2008 + * */ + .name = "P5600", + .CP0_PRid = 0x0001A800, + .CP0_Config0 = MIPS_CONFIG0 | (1 << CP0C0_MM) | (1 << CP0C0_AR) | (MMU_TYPE_R4000 << CP0C0_MT), - .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (15 << CP0C1_MMU) | - (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | - (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | - (1 << CP0C1_CA), + .CP0_Config1 = MIPS_CONFIG1 | (0x3F << 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_FP), .CP0_Config2 = MIPS_CONFIG2, .CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | (1 << CP0C3_MSAP) | - (1 << CP0C3_LPA), - .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M), + (1 << CP0C3_BP) | (1 << CP0C3_BI) | (1 << CP0C3_ULRI) | + (1 << CP0C3_RXI) | (1 << CP0C3_LPA) | (1 << CP0C3_VInt), + .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) | (2 << CP0C4_IE) | + (0x1c << CP0C4_KScrExist), .CP0_Config4_rw_bitmask = 0, - .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_UFR) | (1 << CP0C5_LLB) | - (1 << CP0C5_MVH), - .CP0_Config5_rw_bitmask = (0 << CP0C5_M) | (1 << CP0C5_K) | - (1 << CP0C5_CV) | (0 << CP0C5_EVA) | - (1 << CP0C5_MSAEn) | (1 << CP0C5_UFR) | - (0 << CP0C5_NFExists), + .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_MVH) | (1 << CP0C5_LLB), + .CP0_Config5_rw_bitmask = (1 << CP0C5_K) | (1 << CP0C5_CV) | + (1 << CP0C5_MSAEn) | (1 << CP0C5_UFE) | + (1 << CP0C5_FRE) | (1 << CP0C5_UFR), .CP0_LLAddr_rw_bitmask = 0, - .CP0_LLAddr_shift = 4, + .CP0_LLAddr_shift = 0, .SYNCI_Step = 32, .CCRes = 2, - .CP0_Status_rw_bitmask = 0x3778FF1F, - .CP0_PageGrain_rw_bitmask = (1 << CP0PG_ELPA), - .CP1_fcr0 = (1 << FCR0_UFRP) | (1 << FCR0_F64) | (1 << FCR0_L) | - (1 << FCR0_W) | (1 << FCR0_D) | (1 << FCR0_S) | - (0x93 << FCR0_PRID), + .CP0_Status_rw_bitmask = 0x3C68FF1F, + .CP0_PageGrain_rw_bitmask = (1U << CP0PG_RIE) | (1 << CP0PG_XIE) | + (1 << CP0PG_ELPA) | (1 << CP0PG_IEC), + .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_UFRP) | (1 << FCR0_F64) | + (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) | + (1 << FCR0_S) | (0x03 << FCR0_PRID), .SEGBITS = 32, .PABITS = 40, - .insn_flags = CPU_MIPS32R5 | ASE_MIPS16 | ASE_MSA, + .insn_flags = CPU_MIPS32R5 | ASE_MSA, .mmu_type = MMU_TYPE_R4000, }, { -- cgit v1.2.3 From eb02cc3f89013612cb05df23b5441741e902bbd2 Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Wed, 15 Jul 2015 17:05:09 +0200 Subject: target-mips: simplify LWL/LDL mask generation The LWL/LDL instructions mask the GPR with a mask depending on the address alignement. It is currently computed by doing: mask = 0x7fffffffffffffffull >> (t1 ^ 63) It's simpler to generate it by doing: mask = ~(-1 << t1) It uses one TCG instruction less, and it avoids a 32/64-bit constant loading which can take a few instructions on RISC hosts. Cc: Leon Alrae Signed-off-by: Aurelien Jarno Reviewed-by: Richard Henderson Reviewed-by: Leon Alrae Signed-off-by: Leon Alrae --- target-mips/translate.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index 22ef84df9e..98cf72de74 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -2153,11 +2153,10 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, tcg_gen_andi_tl(t0, t0, ~7); tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ); tcg_gen_shl_tl(t0, t0, t1); - tcg_gen_xori_tl(t1, t1, 63); - t2 = tcg_const_tl(0x7fffffffffffffffull); - tcg_gen_shr_tl(t2, t2, t1); + t2 = tcg_const_tl(-1); + tcg_gen_shl_tl(t2, t2, t1); gen_load_gpr(t1, rt); - tcg_gen_and_tl(t1, t1, t2); + tcg_gen_andc_tl(t1, t1, t2); tcg_temp_free(t2); tcg_gen_or_tl(t0, t0, t1); tcg_temp_free(t1); @@ -2246,11 +2245,10 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, tcg_gen_andi_tl(t0, t0, ~3); tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL); tcg_gen_shl_tl(t0, t0, t1); - tcg_gen_xori_tl(t1, t1, 31); - t2 = tcg_const_tl(0x7fffffffull); - tcg_gen_shr_tl(t2, t2, t1); + t2 = tcg_const_tl(-1); + tcg_gen_shl_tl(t2, t2, t1); gen_load_gpr(t1, rt); - tcg_gen_and_tl(t1, t1, t2); + tcg_gen_andc_tl(t1, t1, t2); tcg_temp_free(t2); tcg_gen_or_tl(t0, t0, t1); tcg_temp_free(t1); -- cgit v1.2.3 From 58d479786b11a7e982419c1e0905b8490ef9a787 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 30 Jul 2015 16:33:42 +0100 Subject: hw/pci-host/bonito: Avoid buffer overrun for bad LDMA/COP accesses The LDMA and COP memory regions represent four 32 bit registers each, but the memory regions themselves are 0x100 bytes large. Add guards to the read and write accessors so that bogus accesses beyond the four defined registers don't just run off the end of the bonldma and boncop structs and into whatever lies beyond. Signed-off-by: Peter Maydell Acked-by: Aurelien Jarno Signed-off-by: Leon Alrae --- hw/pci-host/bonito.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c index 3a731fe18d..4139a2c468 100644 --- a/hw/pci-host/bonito.c +++ b/hw/pci-host/bonito.c @@ -355,6 +355,10 @@ static uint64_t bonito_ldma_readl(void *opaque, hwaddr addr, uint32_t val; PCIBonitoState *s = opaque; + if (addr >= sizeof(s->bonldma)) { + return 0; + } + val = ((uint32_t *)(&s->bonldma))[addr/sizeof(uint32_t)]; return val; @@ -365,6 +369,10 @@ static void bonito_ldma_writel(void *opaque, hwaddr addr, { PCIBonitoState *s = opaque; + if (addr >= sizeof(s->bonldma)) { + return; + } + ((uint32_t *)(&s->bonldma))[addr/sizeof(uint32_t)] = val & 0xffffffff; } @@ -384,6 +392,10 @@ static uint64_t bonito_cop_readl(void *opaque, hwaddr addr, uint32_t val; PCIBonitoState *s = opaque; + if (addr >= sizeof(s->boncop)) { + return 0; + } + val = ((uint32_t *)(&s->boncop))[addr/sizeof(uint32_t)]; return val; @@ -394,6 +406,10 @@ static void bonito_cop_writel(void *opaque, hwaddr addr, { PCIBonitoState *s = opaque; + if (addr >= sizeof(s->boncop)) { + return; + } + ((uint32_t *)(&s->boncop))[addr/sizeof(uint32_t)] = val & 0xffffffff; } -- cgit v1.2.3 From c85570163bdf1ba29cb52a63f22ff1c48f1b9398 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 3 Aug 2015 11:49:12 -0700 Subject: target-mips: Use CPU_LOG_INT for logging related to interrupts There are now no unconditional uses of qemu_log in the subdirectory. Signed-off-by: Richard Henderson Reviewed-by: Aurelien Jarno Reviewed-by: Leon Alrae Signed-off-by: Leon Alrae --- target-mips/helper.c | 30 +++++++++++------------------- target-mips/op_helper.c | 3 ++- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/target-mips/helper.c b/target-mips/helper.c index 04ba19fd44..f44edbbdbb 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -127,10 +127,6 @@ static int get_physical_address (CPUMIPSState *env, hwaddr *physical, /* effective address (modified for KVM T&E kernel segments) */ target_ulong address = real_address; -#if 0 - qemu_log("user mode %d h %08x\n", user_mode, env->hflags); -#endif - #define USEG_LIMIT 0x7FFFFFFFUL #define KSEG0_BASE 0x80000000UL #define KSEG1_BASE 0xA0000000UL @@ -227,11 +223,6 @@ static int get_physical_address (CPUMIPSState *env, hwaddr *physical, ret = TLBRET_BADADDR; } } -#if 0 - qemu_log(TARGET_FMT_lx " %d %d => %" HWADDR_PRIx " %d (%d)\n", - address, rw, access_type, *physical, *prot, ret); -#endif - return ret; } #endif @@ -487,14 +478,16 @@ void mips_cpu_do_interrupt(CPUState *cs) int cause = -1; const char *name; - if (qemu_log_enabled() && cs->exception_index != EXCP_EXT_INTERRUPT) { + if (qemu_loglevel_mask(CPU_LOG_INT) + && cs->exception_index != EXCP_EXT_INTERRUPT) { if (cs->exception_index < 0 || cs->exception_index > EXCP_LAST) { name = "unknown"; } else { name = excp_names[cs->exception_index]; } - qemu_log("%s enter: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " %s exception\n", + qemu_log("%s enter: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx + " %s exception\n", __func__, env->active_tc.PC, env->CP0_EPC, name); } if (cs->exception_index == EXCP_EXT_INTERRUPT && @@ -747,16 +740,15 @@ void mips_cpu_do_interrupt(CPUState *cs) env->CP0_Cause = (env->CP0_Cause & ~(0x1f << CP0Ca_EC)) | (cause << CP0Ca_EC); break; default: - qemu_log("Invalid MIPS exception %d. Exiting\n", cs->exception_index); - printf("Invalid MIPS exception %d. Exiting\n", cs->exception_index); - exit(1); + abort(); } - if (qemu_log_enabled() && cs->exception_index != EXCP_EXT_INTERRUPT) { + if (qemu_loglevel_mask(CPU_LOG_INT) + && cs->exception_index != EXCP_EXT_INTERRUPT) { qemu_log("%s: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " cause %d\n" - " S %08x C %08x A " TARGET_FMT_lx " D " TARGET_FMT_lx "\n", - __func__, env->active_tc.PC, env->CP0_EPC, cause, - env->CP0_Status, env->CP0_Cause, env->CP0_BadVAddr, - env->CP0_DEPC); + " S %08x C %08x A " TARGET_FMT_lx " D " TARGET_FMT_lx "\n", + __func__, env->active_tc.PC, env->CP0_EPC, cause, + env->CP0_Status, env->CP0_Cause, env->CP0_BadVAddr, + env->CP0_DEPC); } #endif cs->exception_index = EXCP_NONE; diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index db4f6b9463..809a061e29 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -38,7 +38,8 @@ static inline void QEMU_NORETURN do_raise_exception_err(CPUMIPSState *env, CPUState *cs = CPU(mips_env_get_cpu(env)); if (exception < EXCP_SC) { - qemu_log("%s: %d %d\n", __func__, exception, error_code); + qemu_log_mask(CPU_LOG_INT, "%s: %d %d\n", + __func__, exception, error_code); } cs->exception_index = exception; env->error_code = error_code; -- cgit v1.2.3