diff options
| author | 2022-11-12 11:26:56 -0500 | |
|---|---|---|
| committer | 2022-11-12 11:26:56 -0500 | |
| commit | 70ea1c20002e8cb9a0f9e98b1992d4c731be0041 (patch) | |
| tree | 72aa8072fad6df71364db1062f3a016ccdfd381e /src | |
| parent | Merge pull request #9167 from vonchenplus/tess (diff) | |
| download | yuzu-70ea1c20002e8cb9a0f9e98b1992d4c731be0041.tar.gz yuzu-70ea1c20002e8cb9a0f9e98b1992d4c731be0041.tar.xz yuzu-70ea1c20002e8cb9a0f9e98b1992d4c731be0041.zip | |
common: add cache management functions
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/common/cache_management.cpp | 60 | ||||
| -rw-r--r-- | src/common/cache_management.h | 27 |
3 files changed, 89 insertions, 0 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index c0555f840..b7c15c191 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt | |||
| @@ -34,6 +34,8 @@ add_library(common STATIC | |||
| 34 | bit_util.h | 34 | bit_util.h |
| 35 | cityhash.cpp | 35 | cityhash.cpp |
| 36 | cityhash.h | 36 | cityhash.h |
| 37 | cache_management.cpp | ||
| 38 | cache_management.h | ||
| 37 | common_funcs.h | 39 | common_funcs.h |
| 38 | common_types.h | 40 | common_types.h |
| 39 | concepts.h | 41 | concepts.h |
diff --git a/src/common/cache_management.cpp b/src/common/cache_management.cpp new file mode 100644 index 000000000..57810b76a --- /dev/null +++ b/src/common/cache_management.cpp | |||
| @@ -0,0 +1,60 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include <cstring> | ||
| 5 | |||
| 6 | #include "alignment.h" | ||
| 7 | #include "cache_management.h" | ||
| 8 | #include "common_types.h" | ||
| 9 | |||
| 10 | namespace Common { | ||
| 11 | |||
| 12 | #if defined(ARCHITECTURE_x86_64) | ||
| 13 | |||
| 14 | // Most cache operations are no-ops on x86 | ||
| 15 | |||
| 16 | void DataCacheLineCleanByVAToPoU(void* start, size_t size) {} | ||
| 17 | void DataCacheLineCleanAndInvalidateByVAToPoC(void* start, size_t size) {} | ||
| 18 | void DataCacheLineCleanByVAToPoC(void* start, size_t size) {} | ||
| 19 | void DataCacheZeroByVA(void* start, size_t size) { | ||
| 20 | std::memset(start, 0, size); | ||
| 21 | } | ||
| 22 | |||
| 23 | #elif defined(ARCHITECTURE_arm64) | ||
| 24 | |||
| 25 | // BS/DminLine is log2(cache size in words), we want size in bytes | ||
| 26 | #define EXTRACT_DMINLINE(ctr_el0) (1 << ((((ctr_el0) >> 16) & 0xf) + 2)) | ||
| 27 | #define EXTRACT_BS(dczid_el0) (1 << (((dczid_el0)&0xf) + 2)) | ||
| 28 | |||
| 29 | #define DEFINE_DC_OP(op_name, function_name) \ | ||
| 30 | void function_name(void* start, size_t size) { \ | ||
| 31 | size_t ctr_el0; \ | ||
| 32 | asm volatile("mrs %[ctr_el0], ctr_el0\n\t" : [ctr_el0] "=r"(ctr_el0)); \ | ||
| 33 | size_t cacheline_size = EXTRACT_DMINLINE(ctr_el0); \ | ||
| 34 | uintptr_t va_start = reinterpret_cast<uintptr_t>(start); \ | ||
| 35 | uintptr_t va_end = va_start + size; \ | ||
| 36 | for (uintptr_t va = va_start; va < va_end; va += cacheline_size) { \ | ||
| 37 | asm volatile("dc " #op_name ", %[va]\n\t" : : [va] "r"(va) : "memory"); \ | ||
| 38 | } \ | ||
| 39 | } | ||
| 40 | |||
| 41 | #define DEFINE_DC_OP_DCZID(op_name, function_name) \ | ||
| 42 | void function_name(void* start, size_t size) { \ | ||
| 43 | size_t dczid_el0; \ | ||
| 44 | asm volatile("mrs %[dczid_el0], dczid_el0\n\t" : [dczid_el0] "=r"(dczid_el0)); \ | ||
| 45 | size_t cacheline_size = EXTRACT_BS(dczid_el0); \ | ||
| 46 | uintptr_t va_start = reinterpret_cast<uintptr_t>(start); \ | ||
| 47 | uintptr_t va_end = va_start + size; \ | ||
| 48 | for (uintptr_t va = va_start; va < va_end; va += cacheline_size) { \ | ||
| 49 | asm volatile("dc " #op_name ", %[va]\n\t" : : [va] "r"(va) : "memory"); \ | ||
| 50 | } \ | ||
| 51 | } | ||
| 52 | |||
| 53 | DEFINE_DC_OP(cvau, DataCacheLineCleanByVAToPoU); | ||
| 54 | DEFINE_DC_OP(civac, DataCacheLineCleanAndInvalidateByVAToPoC); | ||
| 55 | DEFINE_DC_OP(cvac, DataCacheLineCleanByVAToPoC); | ||
| 56 | DEFINE_DC_OP_DCZID(zva, DataCacheZeroByVA); | ||
| 57 | |||
| 58 | #endif | ||
| 59 | |||
| 60 | } // namespace Common | ||
diff --git a/src/common/cache_management.h b/src/common/cache_management.h new file mode 100644 index 000000000..e467b87e4 --- /dev/null +++ b/src/common/cache_management.h | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "stdlib.h" | ||
| 7 | |||
| 8 | namespace Common { | ||
| 9 | |||
| 10 | // Data cache instructions enabled at EL0 by SCTLR_EL1.UCI. | ||
| 11 | // VA = virtual address | ||
| 12 | // PoC = point of coherency | ||
| 13 | // PoU = point of unification | ||
| 14 | |||
| 15 | // dc cvau | ||
| 16 | void DataCacheLineCleanByVAToPoU(void* start, size_t size); | ||
| 17 | |||
| 18 | // dc civac | ||
| 19 | void DataCacheLineCleanAndInvalidateByVAToPoC(void* start, size_t size); | ||
| 20 | |||
| 21 | // dc cvac | ||
| 22 | void DataCacheLineCleanByVAToPoC(void* start, size_t size); | ||
| 23 | |||
| 24 | // dc zva | ||
| 25 | void DataCacheZeroByVA(void* start, size_t size); | ||
| 26 | |||
| 27 | } // namespace Common | ||