- Record address range of block to invalidate. i.e. icbi records ranges

and isync actually invalidate caches
This commit is contained in:
gbeauche 2003-10-12 06:44:04 +00:00
parent 7e0dccc544
commit 1b9876889e
4 changed files with 34 additions and 3 deletions

View File

@ -207,6 +207,9 @@ void powerpc_cpu::initialize()
init_registers();
init_decode_cache();
// Init cache range invalidate recorder
cache_range.start = cache_range.end = 0;
// Init syscalls handler
execute_do_syscall = NULL;

View File

@ -234,6 +234,8 @@ public:
// Caches invalidation
void invalidate_cache();
void invalidate_cache_range(uintptr start, uintptr end);
private:
struct { uintptr start, end; } cache_range;
protected:
@ -325,8 +327,10 @@ private:
void execute_fp_int_convert(uint32 opcode);
template< class Rc >
void execute_fp_round(uint32 opcode);
template< class RA, class RB >
void execute_icbi(uint32 opcode);
void execute_isync(uint32 opcode);
void execute_invalidate_cache_range();
template< class RA, class RB >
void execute_dcbz(uint32 opcode);
};
@ -364,6 +368,7 @@ inline void powerpc_cpu::do_execute()
uint32 dpc = pc() - 4;
do {
uint32 opcode = vm_read_memory_4(dpc += 4);
ii = decode(opcode);
#if PPC_FLIGHT_RECORDER
if (is_logging()) {
di->opcode = opcode;

View File

@ -437,7 +437,7 @@ const powerpc_cpu::instr_info_t powerpc_cpu::powerpc_ii_table[] = {
A_form, 59, 20, CFLOW_NORMAL
},
{ "icbi",
EXECUTE_0(icbi),
EXECUTE_2(icbi, operand_RA_or_0, operand_RB),
NULL,
X_form, 31, 982, CFLOW_NORMAL
},

View File

@ -1098,15 +1098,38 @@ void powerpc_cpu::execute_mftbr(uint32 opcode)
* Instruction cache management
**/
void powerpc_cpu::execute_invalidate_cache_range()
{
if (cache_range.start != cache_range.end) {
D(bug("Invalidate Cache Block [%08x - %08x]\n", cache_range.start, cache_range.end));
invalidate_cache_range(cache_range.start, cache_range.end);
cache_range.start = cache_range.end = 0;
}
}
template< class RA, class RB >
void powerpc_cpu::execute_icbi(uint32 opcode)
{
// TODO: record address range of code to invalidate
const uint32 ea = RA::get(this, opcode) + RB::get(this, opcode);
const uint32 block_start = ea - (ea % 32);
if (block_start == cache_range.end) {
// Extend region to invalidate
cache_range.end += 32;
}
else {
// New region to invalidate
execute_invalidate_cache_range();
cache_range.start = block_start;
cache_range.end = cache_range.start + 32;
}
increment_pc(4);
}
void powerpc_cpu::execute_isync(uint32 opcode)
{
invalidate_cache();
execute_invalidate_cache_range();
increment_pc(4);
}