mirror of
https://github.com/kanjitalk755/macemu.git
synced 2025-01-26 16:31:11 +00:00
- Record address range of block to invalidate. i.e. icbi records ranges
and isync actually invalidate caches
This commit is contained in:
parent
7e0dccc544
commit
1b9876889e
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
},
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user