-
Notifications
You must be signed in to change notification settings - Fork 2.6k
/
PPCCache.h
93 lines (72 loc) · 2.44 KB
/
PPCCache.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// Copyright 2008 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <array>
#include <optional>
#include <vector>
#include "Common/CommonTypes.h"
#include "Common/Config/Config.h"
namespace Core
{
class System;
}
namespace Memory
{
class MemoryManager;
}
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<std::array<std::array<u32, CACHE_BLOCK_SIZE>, 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<std::array<u32, CACHE_WAYS>, CACHE_SETS> addrs{};
std::array<u8, CACHE_SETS> plru{};
std::array<u8, CACHE_SETS> valid{};
std::array<u8, CACHE_SETS> 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<u8> lookup_table{};
std::vector<u8> lookup_table_ex{};
std::vector<u8> lookup_table_vmem{};
Core::System& m_system;
Memory::MemoryManager& m_memory;
explicit Cache(Core::System& system, Memory::MemoryManager& memory);
void Store(u32 addr);
void Invalidate(u32 addr);
void Flush(u32 addr);
void Touch(u32 addr, bool store);
void FlushAll();
std::pair<u32, u32> 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<Config::ConfigChangedCallbackID> m_config_callback_id = std::nullopt;
bool m_disable_icache = false;
explicit InstructionCache(Core::System& system, Memory::MemoryManager& memory)
: Cache(system, memory)
{
}
~InstructionCache();
u32 ReadInstruction(u32 addr);
void Invalidate(u32 addr);
void Init();
void Reset();
void RefreshConfig();
};
} // namespace PowerPC