As icbi is not a priviledge instruction and is treated as a load by the MMU
it needs to be implemented for every MMU translation mode. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2492 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
33d68b5f00
commit
36f696517b
@ -1884,21 +1884,6 @@ void OPPROTO op_td (void)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Instruction cache block invalidate */
|
||||
void OPPROTO op_icbi (void)
|
||||
{
|
||||
do_icbi();
|
||||
RETURN();
|
||||
}
|
||||
|
||||
#if defined(TARGET_PPC64)
|
||||
void OPPROTO op_icbi_64 (void)
|
||||
{
|
||||
do_icbi_64();
|
||||
RETURN();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
/* tlbia */
|
||||
PPC_OP(tlbia)
|
||||
|
@ -808,35 +808,6 @@ void do_td (int flags)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Instruction cache invalidation helper */
|
||||
void do_icbi (void)
|
||||
{
|
||||
uint32_t tmp;
|
||||
/* Invalidate one cache line :
|
||||
* PowerPC specification says this is to be treated like a load
|
||||
* (not a fetch) by the MMU. To be sure it will be so,
|
||||
* do the load "by hand".
|
||||
*/
|
||||
tmp = ldl_kernel((uint32_t)T0);
|
||||
T0 &= ~(ICACHE_LINE_SIZE - 1);
|
||||
tb_invalidate_page_range((uint32_t)T0, (uint32_t)(T0 + ICACHE_LINE_SIZE));
|
||||
}
|
||||
|
||||
#if defined(TARGET_PPC64)
|
||||
void do_icbi_64 (void)
|
||||
{
|
||||
uint64_t tmp;
|
||||
/* Invalidate one cache line :
|
||||
* PowerPC specification says this is to be treated like a load
|
||||
* (not a fetch) by the MMU. To be sure it will be so,
|
||||
* do the load "by hand".
|
||||
*/
|
||||
tmp = ldq_kernel((uint64_t)T0);
|
||||
T0 &= ~(ICACHE_LINE_SIZE - 1);
|
||||
tb_invalidate_page_range((uint64_t)T0, (uint64_t)(T0 + ICACHE_LINE_SIZE));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/* PowerPC 601 specific instructions (POWER bridge) */
|
||||
void do_POWER_abso (void)
|
||||
|
@ -29,6 +29,7 @@ void glue(do_lmw, MEMSUFFIX) (int dst);
|
||||
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_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb);
|
||||
void glue(do_POWER2_lfq, MEMSUFFIX) (void);
|
||||
void glue(do_POWER2_lfq_le, MEMSUFFIX) (void);
|
||||
@ -44,6 +45,7 @@ void glue(do_lmw_64, MEMSUFFIX) (int dst);
|
||||
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);
|
||||
#endif
|
||||
|
||||
#else
|
||||
@ -102,11 +104,6 @@ void do_tw (int flags);
|
||||
#if defined(TARGET_PPC64)
|
||||
void do_td (int flags);
|
||||
#endif
|
||||
void do_icbi (void);
|
||||
#if defined(TARGET_PPC64)
|
||||
void do_icbi_64 (void);
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
void do_rfi (void);
|
||||
#if defined(TARGET_PPC64)
|
||||
|
@ -242,6 +242,35 @@ void glue(do_stsw_le_64, MEMSUFFIX) (int src)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Instruction cache invalidation helper */
|
||||
void glue(do_icbi, MEMSUFFIX) (void)
|
||||
{
|
||||
uint32_t tmp;
|
||||
/* Invalidate one cache line :
|
||||
* PowerPC specification says this is to be treated like a load
|
||||
* (not a fetch) by the MMU. To be sure it will be so,
|
||||
* 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));
|
||||
}
|
||||
|
||||
#if defined(TARGET_PPC64)
|
||||
void glue(do_icbi_64, MEMSUFFIX) (void)
|
||||
{
|
||||
uint64_t tmp;
|
||||
/* Invalidate one cache line :
|
||||
* PowerPC specification says this is to be treated like a load
|
||||
* (not a fetch) by the MMU. To be sure it will be so,
|
||||
* 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));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* PPC 601 specific instructions (POWER bridge) */
|
||||
// XXX: to be tested
|
||||
void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb)
|
||||
|
@ -730,6 +730,21 @@ void OPPROTO glue(op_dcbz_64, MEMSUFFIX) (void)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Instruction cache block invalidate */
|
||||
void OPPROTO glue(op_icbi, MEMSUFFIX) (void)
|
||||
{
|
||||
glue(do_icbi, MEMSUFFIX)();
|
||||
RETURN();
|
||||
}
|
||||
|
||||
#if defined(TARGET_PPC64)
|
||||
void OPPROTO glue(op_icbi_64, MEMSUFFIX) (void)
|
||||
{
|
||||
glue(do_icbi_64, MEMSUFFIX)();
|
||||
RETURN();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* External access */
|
||||
void OPPROTO glue(op_eciwx, MEMSUFFIX) (void)
|
||||
{
|
||||
|
@ -3069,17 +3069,48 @@ GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE)
|
||||
}
|
||||
|
||||
/* icbi */
|
||||
#define op_icbi() (*gen_op_icbi[ctx->mem_idx])()
|
||||
#if defined(TARGET_PPC64)
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
static GenOpFunc *gen_op_icbi[] = {
|
||||
&gen_op_icbi_raw,
|
||||
&gen_op_icbi_raw,
|
||||
&gen_op_icbi_64_raw,
|
||||
&gen_op_icbi_64_raw,
|
||||
};
|
||||
#else
|
||||
static GenOpFunc *gen_op_icbi[] = {
|
||||
&gen_op_icbi_user,
|
||||
&gen_op_icbi_user,
|
||||
&gen_op_icbi_kernel,
|
||||
&gen_op_icbi_kernel,
|
||||
&gen_op_icbi_64_user,
|
||||
&gen_op_icbi_64_user,
|
||||
&gen_op_icbi_64_kernel,
|
||||
&gen_op_icbi_64_kernel,
|
||||
};
|
||||
#endif
|
||||
#else
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
static GenOpFunc *gen_op_icbi[] = {
|
||||
&gen_op_icbi_raw,
|
||||
&gen_op_icbi_raw,
|
||||
};
|
||||
#else
|
||||
static GenOpFunc *gen_op_icbi[] = {
|
||||
&gen_op_icbi_user,
|
||||
&gen_op_icbi_user,
|
||||
&gen_op_icbi_kernel,
|
||||
&gen_op_icbi_kernel,
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE)
|
||||
{
|
||||
/* NIP cannot be restored if the memory exception comes from an helper */
|
||||
gen_update_nip(ctx, ctx->nip - 4);
|
||||
gen_addr_reg_index(ctx);
|
||||
#if defined(TARGET_PPC64)
|
||||
if (ctx->sf_mode)
|
||||
gen_op_icbi_64();
|
||||
else
|
||||
#endif
|
||||
gen_op_icbi();
|
||||
op_icbi();
|
||||
RET_STOP(ctx);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user