diff options
Diffstat (limited to 'src/core/hle/kernel')
| -rw-r--r-- | src/core/hle/kernel/k_page_table.cpp | 45 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_page_table.h | 7 |
2 files changed, 40 insertions, 12 deletions
diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp index 4d564a04f..ebc540316 100644 --- a/src/core/hle/kernel/k_page_table.cpp +++ b/src/core/hle/kernel/k_page_table.cpp | |||
| @@ -3280,21 +3280,16 @@ Result KPageTable::CheckMemoryStateContiguous(size_t* out_blocks_needed, KProces | |||
| 3280 | 3280 | ||
| 3281 | Result KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm, | 3281 | Result KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm, |
| 3282 | KMemoryAttribute* out_attr, size_t* out_blocks_needed, | 3282 | KMemoryAttribute* out_attr, size_t* out_blocks_needed, |
| 3283 | KProcessAddress addr, size_t size, KMemoryState state_mask, | 3283 | KMemoryBlockManager::const_iterator it, |
| 3284 | KProcessAddress last_addr, KMemoryState state_mask, | ||
| 3284 | KMemoryState state, KMemoryPermission perm_mask, | 3285 | KMemoryState state, KMemoryPermission perm_mask, |
| 3285 | KMemoryPermission perm, KMemoryAttribute attr_mask, | 3286 | KMemoryPermission perm, KMemoryAttribute attr_mask, |
| 3286 | KMemoryAttribute attr, KMemoryAttribute ignore_attr) const { | 3287 | KMemoryAttribute attr, KMemoryAttribute ignore_attr) const { |
| 3287 | ASSERT(this->IsLockedByCurrentThread()); | 3288 | ASSERT(this->IsLockedByCurrentThread()); |
| 3288 | 3289 | ||
| 3289 | // Get information about the first block. | 3290 | // Get information about the first block. |
| 3290 | const KProcessAddress last_addr = addr + size - 1; | ||
| 3291 | KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(addr); | ||
| 3292 | KMemoryInfo info = it->GetMemoryInfo(); | 3291 | KMemoryInfo info = it->GetMemoryInfo(); |
| 3293 | 3292 | ||
| 3294 | // If the start address isn't aligned, we need a block. | ||
| 3295 | const size_t blocks_for_start_align = | ||
| 3296 | (Common::AlignDown(GetInteger(addr), PageSize) != info.GetAddress()) ? 1 : 0; | ||
| 3297 | |||
| 3298 | // Validate all blocks in the range have correct state. | 3293 | // Validate all blocks in the range have correct state. |
| 3299 | const KMemoryState first_state = info.m_state; | 3294 | const KMemoryState first_state = info.m_state; |
| 3300 | const KMemoryPermission first_perm = info.m_permission; | 3295 | const KMemoryPermission first_perm = info.m_permission; |
| @@ -3320,10 +3315,6 @@ Result KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission* | |||
| 3320 | info = it->GetMemoryInfo(); | 3315 | info = it->GetMemoryInfo(); |
| 3321 | } | 3316 | } |
| 3322 | 3317 | ||
| 3323 | // If the end address isn't aligned, we need a block. | ||
| 3324 | const size_t blocks_for_end_align = | ||
| 3325 | (Common::AlignUp(GetInteger(addr) + size, PageSize) != info.GetEndAddress()) ? 1 : 0; | ||
| 3326 | |||
| 3327 | // Write output state. | 3318 | // Write output state. |
| 3328 | if (out_state != nullptr) { | 3319 | if (out_state != nullptr) { |
| 3329 | *out_state = first_state; | 3320 | *out_state = first_state; |
| @@ -3334,9 +3325,39 @@ Result KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission* | |||
| 3334 | if (out_attr != nullptr) { | 3325 | if (out_attr != nullptr) { |
| 3335 | *out_attr = static_cast<KMemoryAttribute>(first_attr & ~ignore_attr); | 3326 | *out_attr = static_cast<KMemoryAttribute>(first_attr & ~ignore_attr); |
| 3336 | } | 3327 | } |
| 3328 | |||
| 3329 | // If the end address isn't aligned, we need a block. | ||
| 3337 | if (out_blocks_needed != nullptr) { | 3330 | if (out_blocks_needed != nullptr) { |
| 3338 | *out_blocks_needed = blocks_for_start_align + blocks_for_end_align; | 3331 | const size_t blocks_for_end_align = |
| 3332 | (Common::AlignDown(GetInteger(last_addr), PageSize) + PageSize != info.GetEndAddress()) | ||
| 3333 | ? 1 | ||
| 3334 | : 0; | ||
| 3335 | *out_blocks_needed = blocks_for_end_align; | ||
| 3336 | } | ||
| 3337 | |||
| 3338 | R_SUCCEED(); | ||
| 3339 | } | ||
| 3340 | |||
| 3341 | Result KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm, | ||
| 3342 | KMemoryAttribute* out_attr, size_t* out_blocks_needed, | ||
| 3343 | KProcessAddress addr, size_t size, KMemoryState state_mask, | ||
| 3344 | KMemoryState state, KMemoryPermission perm_mask, | ||
| 3345 | KMemoryPermission perm, KMemoryAttribute attr_mask, | ||
| 3346 | KMemoryAttribute attr, KMemoryAttribute ignore_attr) const { | ||
| 3347 | ASSERT(this->IsLockedByCurrentThread()); | ||
| 3348 | |||
| 3349 | // Check memory state. | ||
| 3350 | const KProcessAddress last_addr = addr + size - 1; | ||
| 3351 | KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(addr); | ||
| 3352 | R_TRY(this->CheckMemoryState(out_state, out_perm, out_attr, out_blocks_needed, it, last_addr, | ||
| 3353 | state_mask, state, perm_mask, perm, attr_mask, attr, ignore_attr)); | ||
| 3354 | |||
| 3355 | // If the start address isn't aligned, we need a block. | ||
| 3356 | if (out_blocks_needed != nullptr && | ||
| 3357 | Common::AlignDown(GetInteger(addr), PageSize) != it->GetAddress()) { | ||
| 3358 | ++(*out_blocks_needed); | ||
| 3339 | } | 3359 | } |
| 3360 | |||
| 3340 | R_SUCCEED(); | 3361 | R_SUCCEED(); |
| 3341 | } | 3362 | } |
| 3342 | 3363 | ||
diff --git a/src/core/hle/kernel/k_page_table.h b/src/core/hle/kernel/k_page_table.h index af12582d9..e69498f02 100644 --- a/src/core/hle/kernel/k_page_table.h +++ b/src/core/hle/kernel/k_page_table.h | |||
| @@ -263,6 +263,13 @@ private: | |||
| 263 | KMemoryAttribute attr_mask, KMemoryAttribute attr) const; | 263 | KMemoryAttribute attr_mask, KMemoryAttribute attr) const; |
| 264 | Result CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm, | 264 | Result CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm, |
| 265 | KMemoryAttribute* out_attr, size_t* out_blocks_needed, | 265 | KMemoryAttribute* out_attr, size_t* out_blocks_needed, |
| 266 | KMemoryBlockManager::const_iterator it, KProcessAddress last_addr, | ||
| 267 | KMemoryState state_mask, KMemoryState state, | ||
| 268 | KMemoryPermission perm_mask, KMemoryPermission perm, | ||
| 269 | KMemoryAttribute attr_mask, KMemoryAttribute attr, | ||
| 270 | KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) const; | ||
| 271 | Result CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm, | ||
| 272 | KMemoryAttribute* out_attr, size_t* out_blocks_needed, | ||
| 266 | KProcessAddress addr, size_t size, KMemoryState state_mask, | 273 | KProcessAddress addr, size_t size, KMemoryState state_mask, |
| 267 | KMemoryState state, KMemoryPermission perm_mask, KMemoryPermission perm, | 274 | KMemoryState state, KMemoryPermission perm_mask, KMemoryPermission perm, |
| 268 | KMemoryAttribute attr_mask, KMemoryAttribute attr, | 275 | KMemoryAttribute attr_mask, KMemoryAttribute attr, |