Address more review comments
This commit is contained in:
parent
d040b27a35
commit
9ff8d0f3e6
8 changed files with 84 additions and 19 deletions
|
@ -82,8 +82,8 @@ abstract class SettingsItem(
|
||||||
IntSetting.CPU_BACKEND,
|
IntSetting.CPU_BACKEND,
|
||||||
R.string.cpu_backend,
|
R.string.cpu_backend,
|
||||||
0,
|
0,
|
||||||
R.array.cpuBackendNames,
|
R.array.cpuBackendArm64Names,
|
||||||
R.array.cpuBackendValues
|
R.array.cpuBackendArm64Values
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
put(
|
put(
|
||||||
|
|
|
@ -175,16 +175,24 @@
|
||||||
<item>2</item>
|
<item>2</item>
|
||||||
</integer-array>
|
</integer-array>
|
||||||
|
|
||||||
<string-array name="cpuBackendNames">
|
<string-array name="cpuBackendArm64Names">
|
||||||
<item>@string/cpu_backend_dynarmic</item>
|
<item>@string/cpu_backend_dynarmic</item>
|
||||||
<item>@string/cpu_backend_nce</item>
|
<item>@string/cpu_backend_nce</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<integer-array name="cpuBackendValues">
|
<integer-array name="cpuBackendArm64Values">
|
||||||
<item>0</item>
|
<item>0</item>
|
||||||
<item>1</item>
|
<item>1</item>
|
||||||
</integer-array>
|
</integer-array>
|
||||||
|
|
||||||
|
<string-array name="cpuBackendX86Names">
|
||||||
|
<item>@string/cpu_backend_dynarmic</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<integer-array name="cpuBackendX86Values">
|
||||||
|
<item>0</item>
|
||||||
|
</integer-array>
|
||||||
|
|
||||||
<string-array name="cpuAccuracyNames">
|
<string-array name="cpuAccuracyNames">
|
||||||
<item>@string/auto</item>
|
<item>@string/auto</item>
|
||||||
<item>@string/cpu_accuracy_accurate</item>
|
<item>@string/cpu_accuracy_accurate</item>
|
||||||
|
|
|
@ -185,7 +185,7 @@
|
||||||
<string name="frame_limit_enable_description">Limits emulation speed to a specified percentage of normal speed.</string>
|
<string name="frame_limit_enable_description">Limits emulation speed to a specified percentage of normal speed.</string>
|
||||||
<string name="frame_limit_slider">Limit speed percent</string>
|
<string name="frame_limit_slider">Limit speed percent</string>
|
||||||
<string name="frame_limit_slider_description">Specifies the percentage to limit emulation speed. 100% is the normal speed. Values higher or lower will increase or decrease the speed limit.</string>
|
<string name="frame_limit_slider_description">Specifies the percentage to limit emulation speed. 100% is the normal speed. Values higher or lower will increase or decrease the speed limit.</string>
|
||||||
<string name="cpu_backend">CPU Backend</string>
|
<string name="cpu_backend">CPU backend</string>
|
||||||
<string name="cpu_accuracy">CPU accuracy</string>
|
<string name="cpu_accuracy">CPU accuracy</string>
|
||||||
<string name="value_with_units">%1$s%2$s</string>
|
<string name="value_with_units">%1$s%2$s</string>
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,10 @@ void Patcher::PatchText(const Kernel::PhysicalMemory& program_image,
|
||||||
WriteMsrHandler(AddRelocations(), oaknut::XReg{static_cast<int>(msr.GetRt())});
|
WriteMsrHandler(AddRelocations(), oaknut::XReg{static_cast<int>(msr.GetRt())});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (auto exclusive = Exclusive{inst}; exclusive.Verify()) {
|
||||||
|
m_exclusives.push_back(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine patching mode for the final relocation step
|
// Determine patching mode for the final relocation step
|
||||||
|
@ -163,12 +167,10 @@ void Patcher::RelocateAndCopy(Common::ProcessAddress load_base,
|
||||||
|
|
||||||
// Cortex-A57 seems to treat all exclusives as ordered, but newer processors do not.
|
// Cortex-A57 seems to treat all exclusives as ordered, but newer processors do not.
|
||||||
// Convert to ordered to preserve this assumption.
|
// Convert to ordered to preserve this assumption.
|
||||||
for (u32 i = ModuleCodeIndex; i < static_cast<u32>(text_words.size()); i++) {
|
for (const ModuleTextAddress i : m_exclusives) {
|
||||||
const u32 inst = text_words[i];
|
auto exclusive = Exclusive{text_words[i]};
|
||||||
if (auto exclusive = Exclusive{inst}; exclusive.Verify()) {
|
|
||||||
text_words[i] = exclusive.AsOrdered();
|
text_words[i] = exclusive.AsOrdered();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Copy to program image
|
// Copy to program image
|
||||||
if (this->mode == PatchMode::PreText) {
|
if (this->mode == PatchMode::PreText) {
|
||||||
|
|
|
@ -93,6 +93,7 @@ private:
|
||||||
std::vector<Relocation> m_branch_to_patch_relocations{};
|
std::vector<Relocation> m_branch_to_patch_relocations{};
|
||||||
std::vector<Relocation> m_branch_to_module_relocations{};
|
std::vector<Relocation> m_branch_to_module_relocations{};
|
||||||
std::vector<Relocation> m_write_module_pc_relocations{};
|
std::vector<Relocation> m_write_module_pc_relocations{};
|
||||||
|
std::vector<ModuleTextAddress> m_exclusives{};
|
||||||
oaknut::Label m_save_context{};
|
oaknut::Label m_save_context{};
|
||||||
oaknut::Label m_load_context{};
|
oaknut::Label m_load_context{};
|
||||||
PatchMode mode{PatchMode::None};
|
PatchMode mode{PatchMode::None};
|
||||||
|
|
|
@ -5678,15 +5678,8 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a
|
||||||
case OperationType::ChangePermissions:
|
case OperationType::ChangePermissions:
|
||||||
case OperationType::ChangePermissionsAndRefresh:
|
case OperationType::ChangePermissionsAndRefresh:
|
||||||
case OperationType::ChangePermissionsAndRefreshAndFlush: {
|
case OperationType::ChangePermissionsAndRefreshAndFlush: {
|
||||||
const bool read = True(properties.perm & Kernel::KMemoryPermission::UserRead);
|
m_memory->ProtectRegion(*m_impl, virt_addr, num_pages * PageSize,
|
||||||
const bool write = True(properties.perm & Kernel::KMemoryPermission::UserWrite);
|
ConvertToMemoryPermission(properties.perm));
|
||||||
// todo: this doesn't really belong here and should go into m_memory to handle rasterizer
|
|
||||||
// access todo: ignore exec on non-direct-mapped case
|
|
||||||
const bool exec = True(properties.perm & Kernel::KMemoryPermission::UserExecute);
|
|
||||||
if (Settings::IsFastmemEnabled()) {
|
|
||||||
m_system.DeviceMemory().buffer.Protect(GetInteger(virt_addr), num_pages * PageSize,
|
|
||||||
read, write, exec);
|
|
||||||
}
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -78,6 +78,51 @@ struct Memory::Impl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProtectRegion(Common::PageTable& page_table, VAddr vaddr, u64 size,
|
||||||
|
Common::MemoryPermission perms) {
|
||||||
|
ASSERT_MSG((size & YUZU_PAGEMASK) == 0, "non-page aligned size: {:016X}", size);
|
||||||
|
ASSERT_MSG((vaddr & YUZU_PAGEMASK) == 0, "non-page aligned base: {:016X}", vaddr);
|
||||||
|
|
||||||
|
if (!Settings::IsFastmemEnabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool is_r = True(perms & Common::MemoryPermission::Read);
|
||||||
|
const bool is_w = True(perms & Common::MemoryPermission::Write);
|
||||||
|
const bool is_x =
|
||||||
|
True(perms & Common::MemoryPermission::Execute) && Settings::IsNceEnabled();
|
||||||
|
|
||||||
|
if (!current_page_table) {
|
||||||
|
system.DeviceMemory().buffer.Protect(vaddr, size, is_r, is_w, is_x);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 protect_bytes{};
|
||||||
|
u64 protect_begin{};
|
||||||
|
for (u64 addr = vaddr; addr < vaddr + size; addr += YUZU_PAGESIZE) {
|
||||||
|
const Common::PageType page_type{
|
||||||
|
current_page_table->pointers[addr >> YUZU_PAGEBITS].Type()};
|
||||||
|
switch (page_type) {
|
||||||
|
case Common::PageType::RasterizerCachedMemory:
|
||||||
|
if (protect_bytes > 0) {
|
||||||
|
system.DeviceMemory().buffer.Protect(protect_begin, protect_bytes, is_r, is_w,
|
||||||
|
is_x);
|
||||||
|
protect_bytes = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (protect_bytes == 0) {
|
||||||
|
protect_begin = addr;
|
||||||
|
}
|
||||||
|
protect_bytes += YUZU_PAGESIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (protect_bytes > 0) {
|
||||||
|
system.DeviceMemory().buffer.Protect(protect_begin, protect_bytes, is_r, is_w, is_x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] u8* GetPointerFromRasterizerCachedMemory(u64 vaddr) const {
|
[[nodiscard]] u8* GetPointerFromRasterizerCachedMemory(u64 vaddr) const {
|
||||||
const Common::PhysicalAddress paddr{
|
const Common::PhysicalAddress paddr{
|
||||||
current_page_table->backing_addr[vaddr >> YUZU_PAGEBITS]};
|
current_page_table->backing_addr[vaddr >> YUZU_PAGEBITS]};
|
||||||
|
@ -839,6 +884,11 @@ void Memory::UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress b
|
||||||
impl->UnmapRegion(page_table, base, size);
|
impl->UnmapRegion(page_table, base, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Memory::ProtectRegion(Common::PageTable& page_table, Common::ProcessAddress vaddr, u64 size,
|
||||||
|
Common::MemoryPermission perms) {
|
||||||
|
impl->ProtectRegion(page_table, GetInteger(vaddr), size, perms);
|
||||||
|
}
|
||||||
|
|
||||||
bool Memory::IsValidVirtualAddress(const Common::ProcessAddress vaddr) const {
|
bool Memory::IsValidVirtualAddress(const Common::ProcessAddress vaddr) const {
|
||||||
const Kernel::KProcess& process = *system.ApplicationProcess();
|
const Kernel::KProcess& process = *system.ApplicationProcess();
|
||||||
const auto& page_table = process.GetPageTable().GetImpl();
|
const auto& page_table = process.GetPageTable().GetImpl();
|
||||||
|
|
|
@ -97,6 +97,17 @@ public:
|
||||||
*/
|
*/
|
||||||
void UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size);
|
void UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protects a region of the emulated process address space with the new permissions.
|
||||||
|
*
|
||||||
|
* @param page_table The page table of the emulated process.
|
||||||
|
* @param base The start address to re-protect. Must be page-aligned.
|
||||||
|
* @param size The amount of bytes to protect. Must be page-aligned.
|
||||||
|
* @param perms The permissions the address range is mapped.
|
||||||
|
*/
|
||||||
|
void ProtectRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size,
|
||||||
|
Common::MemoryPermission perms);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether or not the supplied address is a valid virtual
|
* Checks whether or not the supplied address is a valid virtual
|
||||||
* address for the current process.
|
* address for the current process.
|
||||||
|
|
Loading…
Reference in a new issue