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:
j_mayer 2007-03-18 08:47:10 +00:00
parent 33d68b5f00
commit 36f696517b
6 changed files with 83 additions and 55 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)
{

View File

@ -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);
}