From 1b9876889ea0f2196cdd42195c555214df736e4e Mon Sep 17 00:00:00 2001 From: gbeauche <> Date: Sun, 12 Oct 2003 06:44:04 +0000 Subject: [PATCH] - Record address range of block to invalidate. i.e. icbi records ranges and isync actually invalidate caches --- .../src/kpx_cpu/src/cpu/ppc/ppc-cpu.cpp | 3 +++ .../src/kpx_cpu/src/cpu/ppc/ppc-cpu.hpp | 5 ++++ .../src/kpx_cpu/src/cpu/ppc/ppc-decode.cpp | 2 +- .../src/kpx_cpu/src/cpu/ppc/ppc-execute.cpp | 27 +++++++++++++++++-- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-cpu.cpp b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-cpu.cpp index 8c4fbb97..1a06c930 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-cpu.cpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-cpu.cpp @@ -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; diff --git a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-cpu.hpp b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-cpu.hpp index 7d6cec52..5eeed0ff 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-cpu.hpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-cpu.hpp @@ -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; diff --git a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-decode.cpp b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-decode.cpp index a3b1b316..ac7820d1 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-decode.cpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-decode.cpp @@ -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 }, diff --git a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-execute.cpp b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-execute.cpp index 910f93aa..46af83a2 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-execute.cpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-execute.cpp @@ -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); }