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
|
#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)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
/* tlbia */
|
/* tlbia */
|
||||||
PPC_OP(tlbia)
|
PPC_OP(tlbia)
|
||||||
|
|
|
@ -808,35 +808,6 @@ void do_td (int flags)
|
||||||
}
|
}
|
||||||
#endif
|
#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) */
|
/* PowerPC 601 specific instructions (POWER bridge) */
|
||||||
void do_POWER_abso (void)
|
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_lmw_le, MEMSUFFIX) (int dst);
|
||||||
void glue(do_stmw, MEMSUFFIX) (int src);
|
void glue(do_stmw, MEMSUFFIX) (int src);
|
||||||
void glue(do_stmw_le, 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_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb);
|
||||||
void glue(do_POWER2_lfq, MEMSUFFIX) (void);
|
void glue(do_POWER2_lfq, MEMSUFFIX) (void);
|
||||||
void glue(do_POWER2_lfq_le, 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_lmw_le_64, MEMSUFFIX) (int dst);
|
||||||
void glue(do_stmw_64, MEMSUFFIX) (int src);
|
void glue(do_stmw_64, MEMSUFFIX) (int src);
|
||||||
void glue(do_stmw_le_64, MEMSUFFIX) (int src);
|
void glue(do_stmw_le_64, MEMSUFFIX) (int src);
|
||||||
|
void glue(do_icbi_64, MEMSUFFIX) (void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -102,11 +104,6 @@ void do_tw (int flags);
|
||||||
#if defined(TARGET_PPC64)
|
#if defined(TARGET_PPC64)
|
||||||
void do_td (int flags);
|
void do_td (int flags);
|
||||||
#endif
|
#endif
|
||||||
void do_icbi (void);
|
|
||||||
#if defined(TARGET_PPC64)
|
|
||||||
void do_icbi_64 (void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
void do_rfi (void);
|
void do_rfi (void);
|
||||||
#if defined(TARGET_PPC64)
|
#if defined(TARGET_PPC64)
|
||||||
|
|
|
@ -242,6 +242,35 @@ void glue(do_stsw_le_64, MEMSUFFIX) (int src)
|
||||||
}
|
}
|
||||||
#endif
|
#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) */
|
/* PPC 601 specific instructions (POWER bridge) */
|
||||||
// XXX: to be tested
|
// XXX: to be tested
|
||||||
void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb)
|
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
|
#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 */
|
/* External access */
|
||||||
void OPPROTO glue(op_eciwx, MEMSUFFIX) (void)
|
void OPPROTO glue(op_eciwx, MEMSUFFIX) (void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -3069,17 +3069,48 @@ GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* icbi */
|
/* 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)
|
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE)
|
||||||
{
|
{
|
||||||
/* NIP cannot be restored if the memory exception comes from an helper */
|
/* NIP cannot be restored if the memory exception comes from an helper */
|
||||||
gen_update_nip(ctx, ctx->nip - 4);
|
gen_update_nip(ctx, ctx->nip - 4);
|
||||||
gen_addr_reg_index(ctx);
|
gen_addr_reg_index(ctx);
|
||||||
#if defined(TARGET_PPC64)
|
op_icbi();
|
||||||
if (ctx->sf_mode)
|
|
||||||
gen_op_icbi_64();
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
gen_op_icbi();
|
|
||||||
RET_STOP(ctx);
|
RET_STOP(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue