diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 54baeb8225..43b8c90b1b 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -82,12 +82,6 @@ typedef uint32_t ppc_gpr_t; #define ELF_MACHINE EM_PPC #endif -/* XXX: this should be tunable: PowerPC 601 & 64 bits PowerPC - * have different cache line sizes - */ -#define ICACHE_LINE_SIZE 32 -#define DCACHE_LINE_SIZE 32 - /*****************************************************************************/ /* MMU model */ enum { @@ -521,6 +515,9 @@ struct CPUPPCState { /* 403 dedicated access protection registers */ target_ulong pb[4]; + int dcache_line_size; + int icache_line_size; + /* Those resources are used during exception processing */ /* CPU model definition */ target_ulong msr_mask; @@ -546,6 +543,7 @@ struct CPUPPCState { target_ulong excp_prefix; target_ulong ivor_mask; target_ulong ivpr_mask; + target_ulong hreset_vector; #endif /* Those resources are used only during code translation */ @@ -1052,6 +1050,7 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val); #define SPR_601_HID5 (0x3F5) #define SPR_40x_DAC1 (0x3F6) #define SPR_MSSCR0 (0x3F6) +#define SPR_970_HID5 (0x3F6) #define SPR_MSSSR0 (0x3F7) #define SPR_DABRX (0x3F7) #define SPR_40x_DAC2 (0x3F7) diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c index 8bb93ed36b..56d2af75d1 100644 --- a/target-ppc/op_helper.c +++ b/target-ppc/op_helper.c @@ -1061,21 +1061,21 @@ void do_POWER_clcs (void) switch (T0) { case 0x0CUL: /* Instruction cache line size */ - T0 = ICACHE_LINE_SIZE; + T0 = env->icache_line_size; break; case 0x0DUL: /* Data cache line size */ - T0 = DCACHE_LINE_SIZE; + T0 = env->dcache_line_size; break; case 0x0EUL: /* Minimum cache line size */ - T0 = ICACHE_LINE_SIZE < DCACHE_LINE_SIZE ? - ICACHE_LINE_SIZE : DCACHE_LINE_SIZE; + T0 = env->icache_line_size < env->dcache_line_size ? + env->icache_line_size : env->dcache_line_size; break; case 0x0FUL: /* Maximum cache line size */ - T0 = ICACHE_LINE_SIZE > DCACHE_LINE_SIZE ? - ICACHE_LINE_SIZE : DCACHE_LINE_SIZE; + T0 = env->icache_line_size > env->dcache_line_size ? + env->icache_line_size : env->dcache_line_size; break; default: /* Undefined */ diff --git a/target-ppc/op_helper.h b/target-ppc/op_helper.h index 0406682c76..65bee1ae72 100644 --- a/target-ppc/op_helper.h +++ b/target-ppc/op_helper.h @@ -30,6 +30,7 @@ void glue(do_lmw_le, MEMSUFFIX) (int dst); void glue(do_stmw, MEMSUFFIX) (int src); void glue(do_stmw_le, MEMSUFFIX) (int src); void glue(do_icbi, MEMSUFFIX) (void); +void glue(do_dcbz, MEMSUFFIX) (void); void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb); void glue(do_POWER2_lfq, MEMSUFFIX) (void); void glue(do_POWER2_lfq_le, MEMSUFFIX) (void); @@ -46,6 +47,7 @@ void glue(do_lmw_le_64, MEMSUFFIX) (int dst); void glue(do_stmw_64, MEMSUFFIX) (int src); void glue(do_stmw_le_64, MEMSUFFIX) (int src); void glue(do_icbi_64, MEMSUFFIX) (void); +void glue(do_dcbz_64, MEMSUFFIX) (void); #endif #else diff --git a/target-ppc/op_helper_mem.h b/target-ppc/op_helper_mem.h index e8cca09e92..f5cb6970c4 100644 --- a/target-ppc/op_helper_mem.h +++ b/target-ppc/op_helper_mem.h @@ -252,8 +252,9 @@ void glue(do_icbi, MEMSUFFIX) (void) * do the load "by hand". */ tmp = glue(ldl, MEMSUFFIX)((uint32_t)T0); - T0 &= ~(ICACHE_LINE_SIZE - 1); - tb_invalidate_page_range((uint32_t)T0, (uint32_t)(T0 + ICACHE_LINE_SIZE)); + T0 &= ~(env->icache_line_size - 1); + tb_invalidate_page_range((uint32_t)T0, + (uint32_t)(T0 + env->icache_line_size)); } #if defined(TARGET_PPC64) @@ -266,8 +267,101 @@ void glue(do_icbi_64, MEMSUFFIX) (void) * do the load "by hand". */ tmp = glue(ldq, MEMSUFFIX)((uint64_t)T0); - T0 &= ~(ICACHE_LINE_SIZE - 1); - tb_invalidate_page_range((uint64_t)T0, (uint64_t)(T0 + ICACHE_LINE_SIZE)); + T0 &= ~(env->icache_line_size - 1); + tb_invalidate_page_range((uint64_t)T0, + (uint64_t)(T0 + env->icache_line_size)); +} +#endif + +void glue(do_dcbz, MEMSUFFIX) (void) +{ + int dcache_line_size = env->dcache_line_size; + + /* XXX: should be 970 specific (?) */ + if (((env->spr[SPR_970_HID5] >> 7) & 0x3) == 1) + dcache_line_size = 32; + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x00), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x04), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x08), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x0C), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x10), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x14), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x18), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x1C), 0); + if (dcache_line_size >= 64) { + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x20UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x24UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x28UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x2CUL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x30UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x34UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x38UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x3CUL), 0); + if (dcache_line_size >= 128) { + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x40UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x44UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x48UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x4CUL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x50UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x54UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x58UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x5CUL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x60UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x64UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x68UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x6CUL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x70UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x74UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x78UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x7CUL), 0); + } + } +} + +#if defined(TARGET_PPC64) +void glue(do_dcbz_64, MEMSUFFIX) (void) +{ + int dcache_line_size = env->dcache_line_size; + + /* XXX: should be 970 specific (?) */ + if (((env->spr[SPR_970_HID5] >> 7) & 0x3) == 1) + dcache_line_size = 32; + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x00), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x04), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x08), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x0C), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x10), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x14), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x18), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x1C), 0); + if (dcache_line_size >= 64) { + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x20UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x24UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x28UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x2CUL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x30UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x34UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x38UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x3CUL), 0); + if (dcache_line_size >= 128) { + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x40UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x44UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x48UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x4CUL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x50UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x54UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x58UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x5CUL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x60UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x64UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x68UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x6CUL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x70UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x74UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x78UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x7CUL), 0); + } + } } #endif diff --git a/target-ppc/op_mem.h b/target-ppc/op_mem.h index 71dfb1e347..16d8667777 100644 --- a/target-ppc/op_mem.h +++ b/target-ppc/op_mem.h @@ -787,7 +787,20 @@ void OPPROTO glue(op_stdcx_le_64, MEMSUFFIX) (void) } #endif -void OPPROTO glue(op_dcbz, MEMSUFFIX) (void) +void OPPROTO glue(op_dcbz_l32, MEMSUFFIX) (void) +{ + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x00), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x04), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x08), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x0C), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x10), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x14), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x18), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x1C), 0); + RETURN(); +} + +void OPPROTO glue(op_dcbz_l64, MEMSUFFIX) (void) { glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x00), 0); glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x04), 0); @@ -797,8 +810,6 @@ void OPPROTO glue(op_dcbz, MEMSUFFIX) (void) glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x14), 0); glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x18), 0); glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x1C), 0); -#if DCACHE_LINE_SIZE == 64 - /* XXX: cache line size should be 64 for POWER & PowerPC 601 */ glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x20UL), 0); glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x24UL), 0); glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x28UL), 0); @@ -807,12 +818,67 @@ void OPPROTO glue(op_dcbz, MEMSUFFIX) (void) glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x34UL), 0); glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x38UL), 0); glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x3CUL), 0); -#endif + RETURN(); +} + +void OPPROTO glue(op_dcbz_l128, MEMSUFFIX) (void) +{ + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x00), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x04), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x08), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x0C), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x10), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x14), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x18), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x1C), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x20UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x24UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x28UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x2CUL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x30UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x34UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x38UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x3CUL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x40UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x44UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x48UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x4CUL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x50UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x54UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x58UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x5CUL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x60UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x64UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x68UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x6CUL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x70UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x74UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x78UL), 0); + glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x7CUL), 0); + RETURN(); +} + +void OPPROTO glue(op_dcbz, MEMSUFFIX) (void) +{ + glue(do_dcbz, MEMSUFFIX)(); RETURN(); } #if defined(TARGET_PPC64) -void OPPROTO glue(op_dcbz_64, MEMSUFFIX) (void) +void OPPROTO glue(op_dcbz_l32_64, MEMSUFFIX) (void) +{ + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x00), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x04), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x08), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x0C), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x10), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x14), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x18), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x1C), 0); + RETURN(); +} + +void OPPROTO glue(op_dcbz_l64_64, MEMSUFFIX) (void) { glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x00), 0); glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x04), 0); @@ -822,8 +888,6 @@ void OPPROTO glue(op_dcbz_64, MEMSUFFIX) (void) glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x14), 0); glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x18), 0); glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x1C), 0); -#if DCACHE_LINE_SIZE == 64 - /* XXX: cache line size should be 64 for POWER & PowerPC 601 */ glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x20UL), 0); glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x24UL), 0); glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x28UL), 0); @@ -832,7 +896,49 @@ void OPPROTO glue(op_dcbz_64, MEMSUFFIX) (void) glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x34UL), 0); glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x38UL), 0); glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x3CUL), 0); -#endif + RETURN(); +} + +void OPPROTO glue(op_dcbz_l128_64, MEMSUFFIX) (void) +{ + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x00), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x04), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x08), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x0C), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x10), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x14), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x18), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x1C), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x20UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x24UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x28UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x2CUL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x30UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x34UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x38UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x3CUL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x40UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x44UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x48UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x4CUL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x50UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x54UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x58UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x5CUL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x60UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x64UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x68UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x6CUL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x70UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x74UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x78UL), 0); + glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x7CUL), 0); + RETURN(); +} + +void OPPROTO glue(op_dcbz_64, MEMSUFFIX) (void) +{ + glue(do_dcbz_64, MEMSUFFIX)(); RETURN(); } #endif diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 5e4b12b03c..77486f3b6a 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -169,6 +169,7 @@ typedef struct DisasContext { #endif ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */ int singlestep_enabled; + int dcache_line_size; } DisasContext; struct opc_handler_t { @@ -482,6 +483,10 @@ enum { PPC_WAIT = 0x0000100000000000ULL, /* New 64 bits extensions (PowerPC 2.0x) */ PPC_64BX = 0x0000200000000000ULL, + /* dcbz instruction with fixed cache line size */ + PPC_CACHE_DCBZ = 0x0000400000000000ULL, + /* dcbz instruction with tunable cache line size */ + PPC_CACHE_DCBZT = 0x0000800000000000ULL, }; /*****************************************************************************/ @@ -3623,51 +3628,178 @@ GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE) } /* dcbz */ -#define op_dcbz() (*gen_op_dcbz[ctx->mem_idx])() +#define op_dcbz(n) (*gen_op_dcbz[n][ctx->mem_idx])() #if defined(CONFIG_USER_ONLY) /* User-mode only */ -static GenOpFunc *gen_op_dcbz[] = { - &gen_op_dcbz_raw, - &gen_op_dcbz_raw, +static GenOpFunc *gen_op_dcbz[4][4] = { + { + &gen_op_dcbz_l32_raw, + &gen_op_dcbz_l32_raw, #if defined(TARGET_PPC64) - &gen_op_dcbz_64_raw, - &gen_op_dcbz_64_raw, + &gen_op_dcbz_l32_64_raw, + &gen_op_dcbz_l32_64_raw, #endif + }, + { + &gen_op_dcbz_l64_raw, + &gen_op_dcbz_l64_raw, +#if defined(TARGET_PPC64) + &gen_op_dcbz_l64_64_raw, + &gen_op_dcbz_l64_64_raw, +#endif + }, + { + &gen_op_dcbz_l128_raw, + &gen_op_dcbz_l128_raw, +#if defined(TARGET_PPC64) + &gen_op_dcbz_l128_64_raw, + &gen_op_dcbz_l128_64_raw, +#endif + }, + { + &gen_op_dcbz_raw, + &gen_op_dcbz_raw, +#if defined(TARGET_PPC64) + &gen_op_dcbz_64_raw, + &gen_op_dcbz_64_raw, +#endif + }, }; #else #if defined(TARGET_PPC64) /* Full system - 64 bits mode */ -static GenOpFunc *gen_op_dcbz[] = { - &gen_op_dcbz_user, - &gen_op_dcbz_user, - &gen_op_dcbz_64_user, - &gen_op_dcbz_64_user, - &gen_op_dcbz_kernel, - &gen_op_dcbz_kernel, - &gen_op_dcbz_64_kernel, - &gen_op_dcbz_64_kernel, +static GenOpFunc *gen_op_dcbz[4][12] = { + { + &gen_op_dcbz_l32_user, + &gen_op_dcbz_l32_user, + &gen_op_dcbz_l32_64_user, + &gen_op_dcbz_l32_64_user, + &gen_op_dcbz_l32_kernel, + &gen_op_dcbz_l32_kernel, + &gen_op_dcbz_l32_64_kernel, + &gen_op_dcbz_l32_64_kernel, #if defined(TARGET_PPC64H) - &gen_op_dcbz_hypv, - &gen_op_dcbz_hypv, - &gen_op_dcbz_64_hypv, - &gen_op_dcbz_64_hypv, + &gen_op_dcbz_l32_hypv, + &gen_op_dcbz_l32_hypv, + &gen_op_dcbz_l32_64_hypv, + &gen_op_dcbz_l32_64_hypv, #endif + }, + { + &gen_op_dcbz_l64_user, + &gen_op_dcbz_l64_user, + &gen_op_dcbz_l64_64_user, + &gen_op_dcbz_l64_64_user, + &gen_op_dcbz_l64_kernel, + &gen_op_dcbz_l64_kernel, + &gen_op_dcbz_l64_64_kernel, + &gen_op_dcbz_l64_64_kernel, +#if defined(TARGET_PPC64H) + &gen_op_dcbz_l64_hypv, + &gen_op_dcbz_l64_hypv, + &gen_op_dcbz_l64_64_hypv, + &gen_op_dcbz_l64_64_hypv, +#endif + }, + { + &gen_op_dcbz_l128_user, + &gen_op_dcbz_l128_user, + &gen_op_dcbz_l128_64_user, + &gen_op_dcbz_l128_64_user, + &gen_op_dcbz_l128_kernel, + &gen_op_dcbz_l128_kernel, + &gen_op_dcbz_l128_64_kernel, + &gen_op_dcbz_l128_64_kernel, +#if defined(TARGET_PPC64H) + &gen_op_dcbz_l128_hypv, + &gen_op_dcbz_l128_hypv, + &gen_op_dcbz_l128_64_hypv, + &gen_op_dcbz_l128_64_hypv, +#endif + }, + { + &gen_op_dcbz_user, + &gen_op_dcbz_user, + &gen_op_dcbz_64_user, + &gen_op_dcbz_64_user, + &gen_op_dcbz_kernel, + &gen_op_dcbz_kernel, + &gen_op_dcbz_64_kernel, + &gen_op_dcbz_64_kernel, +#if defined(TARGET_PPC64H) + &gen_op_dcbz_hypv, + &gen_op_dcbz_hypv, + &gen_op_dcbz_64_hypv, + &gen_op_dcbz_64_hypv, +#endif + }, }; #else /* Full system - 32 bits mode */ -static GenOpFunc *gen_op_dcbz[] = { - &gen_op_dcbz_user, - &gen_op_dcbz_user, - &gen_op_dcbz_kernel, - &gen_op_dcbz_kernel, +static GenOpFunc *gen_op_dcbz[4][4] = { + { + &gen_op_dcbz_l32_user, + &gen_op_dcbz_l32_user, + &gen_op_dcbz_l32_kernel, + &gen_op_dcbz_l32_kernel, + }, + { + &gen_op_dcbz_l64_user, + &gen_op_dcbz_l64_user, + &gen_op_dcbz_l64_kernel, + &gen_op_dcbz_l64_kernel, + }, + { + &gen_op_dcbz_l128_user, + &gen_op_dcbz_l128_user, + &gen_op_dcbz_l128_kernel, + &gen_op_dcbz_l128_kernel, + }, + { + &gen_op_dcbz_user, + &gen_op_dcbz_user, + &gen_op_dcbz_kernel, + &gen_op_dcbz_kernel, + }, }; #endif #endif -GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE) +static inline void handler_dcbz (DisasContext *ctx, int dcache_line_size) +{ + int n; + + switch (dcache_line_size) { + case 32: + n = 0; + break; + case 64: + n = 1; + break; + case 128: + n = 2; + break; + default: + n = 3; + break; + } + op_dcbz(n); +} + +GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE_DCBZ) { gen_addr_reg_index(ctx); - op_dcbz(); + handler_dcbz(ctx, ctx->dcache_line_size); + gen_op_check_reservation(); +} + +GEN_HANDLER(dcbz_970, 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZT) +{ + gen_addr_reg_index(ctx); + if (ctx->opcode & 0x00200000) + handler_dcbz(ctx, ctx->dcache_line_size); + else + handler_dcbz(ctx, -1); gen_op_check_reservation(); } @@ -6341,6 +6473,7 @@ static inline int gen_intermediate_code_internal (CPUState *env, #else ctx.mem_idx = (supervisor << 1) | msr_le; #endif + ctx.dcache_line_size = env->dcache_line_size; ctx.fpu_enabled = msr_fp; #if defined(TARGET_PPCEMB) ctx.spe_enabled = msr_spe; diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 355f5ad073..445cb58186 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -2542,7 +2542,7 @@ static void init_excp_970 (CPUPPCState *env) /* PowerPC implementations definitions */ /* PowerPC 40x instruction set */ -#define POWERPC_INSNS_EMB (PPC_INSNS_BASE | PPC_EMB_COMMON) +#define POWERPC_INSNS_EMB (PPC_INSNS_BASE | PPC_CACHE_DCBZ | PPC_EMB_COMMON) /* PowerPC 401 */ #define POWERPC_INSNS_401 (POWERPC_INSNS_EMB | \ @@ -2560,8 +2560,14 @@ static void init_proc_401 (CPUPPCState *env) gen_spr_401_403(env); gen_spr_401(env); init_excp_4xx_real(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc40x_irq_init(env); +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* PowerPC 401x2 */ @@ -2587,8 +2593,14 @@ static void init_proc_401x2 (CPUPPCState *env) env->nb_ways = 1; env->id_tlbs = 0; init_excp_4xx_softmmu(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc40x_irq_init(env); +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* PowerPC 401x3 */ @@ -2612,8 +2624,14 @@ static void init_proc_401x3 (CPUPPCState *env) gen_spr_401x2(env); gen_spr_compress(env); init_excp_4xx_softmmu(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc40x_irq_init(env); +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* IOP480 */ @@ -2639,8 +2657,14 @@ static void init_proc_IOP480 (CPUPPCState *env) env->nb_ways = 1; env->id_tlbs = 0; init_excp_4xx_softmmu(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc40x_irq_init(env); +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* PowerPC 403 */ @@ -2661,8 +2685,14 @@ static void init_proc_403 (CPUPPCState *env) gen_spr_403(env); gen_spr_403_real(env); init_excp_4xx_real(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc40x_irq_init(env); +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* PowerPC 403 GCX */ @@ -2699,8 +2729,14 @@ static void init_proc_403GCX (CPUPPCState *env) env->nb_ways = 1; env->id_tlbs = 0; init_excp_4xx_softmmu(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc40x_irq_init(env); +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* PowerPC 405 */ @@ -2737,8 +2773,14 @@ static void init_proc_405 (CPUPPCState *env) env->nb_ways = 1; env->id_tlbs = 0; init_excp_4xx_softmmu(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc40x_irq_init(env); +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* PowerPC 440 EP */ @@ -2781,7 +2823,13 @@ static void init_proc_440EP (CPUPPCState *env) env->nb_ways = 1; env->id_tlbs = 0; init_excp_BookE(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* XXX: TODO: allocate internal IRQ controller */ +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* PowerPC 440 GP */ @@ -2806,7 +2854,13 @@ static void init_proc_440GP (CPUPPCState *env) env->nb_ways = 1; env->id_tlbs = 0; init_excp_BookE(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* XXX: TODO: allocate internal IRQ controller */ +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* PowerPC 440x4 */ @@ -2832,7 +2886,13 @@ static void init_proc_440x4 (CPUPPCState *env) env->nb_ways = 1; env->id_tlbs = 0; init_excp_BookE(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* XXX: TODO: allocate internal IRQ controller */ +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* PowerPC 440x5 */ @@ -2875,7 +2935,13 @@ static void init_proc_440x5 (CPUPPCState *env) env->nb_ways = 1; env->id_tlbs = 0; init_excp_BookE(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* XXX: TODO: allocate internal IRQ controller */ +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* PowerPC 460 (guessed) */ @@ -2924,7 +2990,13 @@ static void init_proc_460 (CPUPPCState *env) env->nb_ways = 1; env->id_tlbs = 0; init_excp_BookE(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* XXX: TODO: allocate internal IRQ controller */ +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* PowerPC 460F (guessed) */ @@ -2976,7 +3048,13 @@ static void init_proc_460F (CPUPPCState *env) env->nb_ways = 1; env->id_tlbs = 0; init_excp_BookE(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* XXX: TODO: allocate internal IRQ controller */ +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* Generic BookE PowerPC */ @@ -2997,6 +3075,12 @@ __attribute__ (( unused )) static void init_proc_BookE (CPUPPCState *env) { init_excp_BookE(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* e200 core */ @@ -3025,7 +3109,13 @@ static void init_proc_e500 (CPUPPCState *env) env->nb_ways = 1; env->id_tlbs = 0; init_excp_BookE(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* XXX: TODO: allocate internal IRQ controller */ +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* e600 core */ @@ -3038,7 +3128,7 @@ static void init_proc_e500 (CPUPPCState *env) #define POWERPC_INSNS_WORKS (POWERPC_INSNS_6xx | PPC_FLOAT_FSQRT | \ PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE | \ PPC_FLOAT_FSEL | PPC_FLOAT_STFIWX | \ - PPC_MEM_TLBSYNC | PPC_MFTB) + PPC_MEM_TLBSYNC | PPC_CACHE_DCBZ | PPC_MFTB) /* POWER : same as 601, without mfmsr, mfsr */ #if defined(TODO) @@ -3048,7 +3138,8 @@ static void init_proc_e500 (CPUPPCState *env) #endif /* TODO */ /* PowerPC 601 */ -#define POWERPC_INSNS_601 (POWERPC_INSNS_6xx | PPC_EXTERN | PPC_POWER_BR) +#define POWERPC_INSNS_601 (POWERPC_INSNS_6xx | PPC_CACHE_DCBZ | \ + PPC_EXTERN | PPC_POWER_BR) #define POWERPC_MSRM_601 (0x000000000000FE70ULL) //#define POWERPC_MMU_601 (POWERPC_MMU_601) //#define POWERPC_EXCP_601 (POWERPC_EXCP_601) @@ -3091,14 +3182,21 @@ static void init_proc_601 (CPUPPCState *env) env->id_tlbs = 0; env->id_tlbs = 0; init_excp_601(env); + env->dcache_line_size = 64; + env->icache_line_size = 64; /* XXX: TODO: allocate internal IRQ controller */ +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* PowerPC 602 */ #define POWERPC_INSNS_602 (POWERPC_INSNS_6xx | PPC_MFTB | \ PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE | \ PPC_FLOAT_FSEL | PPC_FLOAT_STFIWX | \ - PPC_6xx_TLB | PPC_MEM_TLBSYNC | PPC_602_SPEC) + PPC_6xx_TLB | PPC_MEM_TLBSYNC | PPC_CACHE_DCBZ |\ + PPC_602_SPEC) #define POWERPC_MSRM_602 (0x000000000033FF73ULL) #define POWERPC_MMU_602 (POWERPC_MMU_SOFT_6xx) //#define POWERPC_EXCP_602 (POWERPC_EXCP_602) @@ -3126,8 +3224,14 @@ static void init_proc_602 (CPUPPCState *env) gen_low_BATs(env); gen_6xx_7xx_soft_tlb(env, 64, 2); init_excp_602(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc6xx_irq_init(env); +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* PowerPC 603 */ @@ -3159,8 +3263,14 @@ static void init_proc_603 (CPUPPCState *env) gen_low_BATs(env); gen_6xx_7xx_soft_tlb(env, 64, 2); init_excp_603(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc6xx_irq_init(env); +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* PowerPC 603e */ @@ -3197,8 +3307,14 @@ static void init_proc_603E (CPUPPCState *env) gen_low_BATs(env); gen_6xx_7xx_soft_tlb(env, 64, 2); init_excp_603(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc6xx_irq_init(env); +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* PowerPC G2 */ @@ -3237,8 +3353,14 @@ static void init_proc_G2 (CPUPPCState *env) gen_high_BATs(env); gen_6xx_7xx_soft_tlb(env, 64, 2); init_excp_G2(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc6xx_irq_init(env); +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* PowerPC G2LE */ @@ -3277,8 +3399,14 @@ static void init_proc_G2LE (CPUPPCState *env) gen_high_BATs(env); gen_6xx_7xx_soft_tlb(env, 64, 2); init_excp_G2(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc6xx_irq_init(env); +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* PowerPC 604 */ @@ -3309,8 +3437,14 @@ static void init_proc_604 (CPUPPCState *env) /* Memory management */ gen_low_BATs(env); init_excp_604(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc6xx_irq_init(env); +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* PowerPC 740/750 (aka G3) */ @@ -3343,8 +3477,14 @@ static void init_proc_7x0 (CPUPPCState *env) /* Memory management */ gen_low_BATs(env); init_excp_7x0(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc6xx_irq_init(env); +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* PowerPC 750FX/GX */ @@ -3384,8 +3524,14 @@ static void init_proc_750fx (CPUPPCState *env) /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */ gen_high_BATs(env); init_excp_750FX(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc6xx_irq_init(env); +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* PowerPC 745/755 */ @@ -3433,8 +3579,14 @@ static void init_proc_7x5 (CPUPPCState *env) gen_low_BATs(env); gen_high_BATs(env); gen_6xx_7xx_soft_tlb(env, 64, 2); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc6xx_irq_init(env); +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* PowerPC 7400 (aka G4) */ @@ -3460,8 +3612,14 @@ static void init_proc_7400 (CPUPPCState *env) /* Memory management */ gen_low_BATs(env); init_excp_7400(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc6xx_irq_init(env); +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* PowerPC 7410 (aka G4) */ @@ -3499,8 +3657,14 @@ static void init_proc_7410 (CPUPPCState *env) /* Memory management */ gen_low_BATs(env); init_excp_7400(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc6xx_irq_init(env); +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* PowerPC 7440 (aka G4) */ @@ -3564,8 +3728,14 @@ static void init_proc_7440 (CPUPPCState *env) /* Memory management */ gen_low_BATs(env); gen_74xx_soft_tlb(env, 128, 2); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc6xx_irq_init(env); +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* PowerPC 7450 (aka G4) */ @@ -3632,8 +3802,14 @@ static void init_proc_7450 (CPUPPCState *env) gen_low_BATs(env); gen_74xx_soft_tlb(env, 128, 2); init_excp_7450(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc6xx_irq_init(env); +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* PowerPC 7445 (aka G4) */ @@ -3732,8 +3908,14 @@ static void init_proc_7445 (CPUPPCState *env) gen_high_BATs(env); gen_74xx_soft_tlb(env, 128, 2); init_excp_7450(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc6xx_irq_init(env); +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } /* PowerPC 7455 (aka G4) */ @@ -3834,13 +4016,23 @@ static void init_proc_7455 (CPUPPCState *env) gen_high_BATs(env); gen_74xx_soft_tlb(env, 128, 2); init_excp_7450(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc6xx_irq_init(env); +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif } #if defined (TARGET_PPC64) +#define POWERPC_INSNS_WORK64 (POWERPC_INSNS_6xx | PPC_FLOAT_FSQRT | \ + PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE | \ + PPC_FLOAT_FSEL | PPC_FLOAT_STFIWX | \ + PPC_MEM_TLBSYNC | PPC_CACHE_DCBZT | PPC_MFTB) /* PowerPC 970 */ -#define POWERPC_INSNS_970 (POWERPC_INSNS_WORKS | PPC_FLOAT_FSQRT | \ +#define POWERPC_INSNS_970 (POWERPC_INSNS_WORK64 | PPC_FLOAT_FSQRT | \ PPC_64B | PPC_ALTIVEC | \ PPC_64_BRIDGE | PPC_SLBI) #define POWERPC_MSRM_970 (0x900000000204FF36ULL) @@ -3860,7 +4052,7 @@ static void init_proc_970 (CPUPPCState *env) spr_register(env, SPR_HID0, "HID0", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_clear, - 0x00000000); + 0x60000000); /* XXX : not implemented */ spr_register(env, SPR_HID1, "HID1", SPR_NOACCESS, SPR_NOACCESS, @@ -3878,12 +4070,18 @@ static void init_proc_970 (CPUPPCState *env) env->slb_nr = 32; #endif init_excp_970(env); + env->dcache_line_size = 128; + env->icache_line_size = 128; /* Allocate hardware IRQ controller */ ppc970_irq_init(env); +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0x0000000000000100ULL; +#endif } /* PowerPC 970FX (aka G5) */ -#define POWERPC_INSNS_970FX (POWERPC_INSNS_WORKS | PPC_FLOAT_FSQRT | \ +#define POWERPC_INSNS_970FX (POWERPC_INSNS_WORK64 | PPC_FLOAT_FSQRT | \ PPC_64B | PPC_ALTIVEC | \ PPC_64_BRIDGE | PPC_SLBI) #define POWERPC_MSRM_970FX (0x800000000204FF36ULL) @@ -3903,7 +4101,7 @@ static void init_proc_970FX (CPUPPCState *env) spr_register(env, SPR_HID0, "HID0", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_clear, - 0x00000000); + 0x60000000); /* XXX : not implemented */ spr_register(env, SPR_HID1, "HID1", SPR_NOACCESS, SPR_NOACCESS, @@ -3914,6 +4112,11 @@ static void init_proc_970FX (CPUPPCState *env) SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); + /* XXX : not implemented */ + spr_register(env, SPR_970_HID5, "HID5", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); /* Memory management */ /* XXX: not correct */ gen_low_BATs(env); @@ -3921,12 +4124,18 @@ static void init_proc_970FX (CPUPPCState *env) env->slb_nr = 32; #endif init_excp_970(env); + env->dcache_line_size = 128; + env->icache_line_size = 128; /* Allocate hardware IRQ controller */ ppc970_irq_init(env); +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0x0000000000000100ULL; +#endif } /* PowerPC 970 GX */ -#define POWERPC_INSNS_970GX (POWERPC_INSNS_WORKS | PPC_FLOAT_FSQRT | \ +#define POWERPC_INSNS_970GX (POWERPC_INSNS_WORK64 | PPC_FLOAT_FSQRT | \ PPC_64B | PPC_ALTIVEC | \ PPC_64_BRIDGE | PPC_SLBI) #define POWERPC_MSRM_970GX (0x800000000204FF36ULL) @@ -3946,7 +4155,7 @@ static void init_proc_970GX (CPUPPCState *env) spr_register(env, SPR_HID0, "HID0", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_clear, - 0x00000000); + 0x60000000); /* XXX : not implemented */ spr_register(env, SPR_HID1, "HID1", SPR_NOACCESS, SPR_NOACCESS, @@ -3957,6 +4166,11 @@ static void init_proc_970GX (CPUPPCState *env) SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); + /* XXX : not implemented */ + spr_register(env, SPR_970_HID5, "HID5", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); /* Memory management */ /* XXX: not correct */ gen_low_BATs(env); @@ -3964,8 +4178,14 @@ static void init_proc_970GX (CPUPPCState *env) env->slb_nr = 32; #endif init_excp_970(env); + env->dcache_line_size = 128; + env->icache_line_size = 128; /* Allocate hardware IRQ controller */ ppc970_irq_init(env); +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0x0000000000000100ULL; +#endif } /* PowerPC 620 */ @@ -3994,7 +4214,13 @@ static void init_proc_620 (CPUPPCState *env) gen_low_BATs(env); gen_high_BATs(env); init_excp_620(env); + env->dcache_line_size = 64; + env->icache_line_size = 64; /* XXX: TODO: initialize internal interrupt controller */ +#if !defined(CONFIG_USER_ONLY) + /* Hardware reset vector */ + env->hreset_vector = 0x0000000000000100ULL; /* ? */ +#endif } #endif /* defined (TARGET_PPC64) */