// Copyright 2008 Dolphin Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once #include #include #include #include "Common/CommonTypes.h" #include "Common/Config/Config.h" class PointerWrap; namespace PowerPC { constexpr u32 CACHE_SETS = 128; constexpr u32 CACHE_WAYS = 8; // size of an instruction cache block in words constexpr u32 CACHE_BLOCK_SIZE = 8; constexpr u32 CACHE_EXRAM_BIT = 0x10000000; constexpr u32 CACHE_VMEM_BIT = 0x20000000; struct Cache { std::array, CACHE_WAYS>, CACHE_SETS> data{}; // Stores the 32-byte aligned address of the start of each cache block. This consists of the cache // set and tag. Real hardware only needs to store the tag, but also including the set simplifies // debugging and getting the actual address in the cache, without changing behavior (as the set // portion of the address is by definition the same for all addresses in a set). std::array, CACHE_SETS> addrs{}; std::array plru{}; std::array valid{}; std::array modified{}; // Note: This is only for performance purposes; this same data could be computed at runtime // from the tags and valid fields (and that's how it's done on the actual cache) std::vector lookup_table{}; std::vector lookup_table_ex{}; std::vector lookup_table_vmem{}; void Store(u32 addr); void Invalidate(u32 addr); void Flush(u32 addr); void Touch(u32 addr, bool store); void FlushAll(); std::pair GetCache(u32 addr, bool locked); void Read(u32 addr, void* buffer, u32 len, bool locked); void Write(u32 addr, const void* buffer, u32 len, bool locked); void Init(); void Reset(); void DoState(PointerWrap& p); }; struct InstructionCache : public Cache { std::optional m_config_callback_id = std::nullopt; bool m_disable_icache = false; InstructionCache() = default; ~InstructionCache(); u32 ReadInstruction(u32 addr); void Invalidate(u32 addr); void Init(); void Reset(); void RefreshConfig(); }; } // namespace PowerPC