mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 12:21:18 +00:00
kern: implement new attr tracking for memory range/traversal context
This commit is contained in:
parent
c0a4fc30a8
commit
952188fc73
5 changed files with 26 additions and 7 deletions
|
@ -30,6 +30,7 @@ namespace ams::kern::arch::arm64 {
|
|||
KPhysicalAddress phys_addr;
|
||||
size_t block_size;
|
||||
u8 sw_reserved_bits;
|
||||
u8 attr;
|
||||
|
||||
constexpr bool IsHeadMergeDisabled() const { return (this->sw_reserved_bits & PageTableEntry::SoftwareReservedBit_DisableMergeHead) != 0; }
|
||||
constexpr bool IsHeadAndBodyMergeDisabled() const { return (this->sw_reserved_bits & PageTableEntry::SoftwareReservedBit_DisableMergeHeadAndBody) != 0; }
|
||||
|
|
|
@ -62,18 +62,21 @@ namespace ams::kern {
|
|||
KPhysicalAddress m_address;
|
||||
size_t m_size;
|
||||
bool m_heap;
|
||||
u8 m_attr;
|
||||
public:
|
||||
constexpr MemoryRange() : m_address(Null<KPhysicalAddress>), m_size(0), m_heap(false) { /* ... */ }
|
||||
constexpr MemoryRange() : m_address(Null<KPhysicalAddress>), m_size(0), m_heap(false), m_attr(0) { /* ... */ }
|
||||
|
||||
void Set(KPhysicalAddress address, size_t size, bool heap) {
|
||||
void Set(KPhysicalAddress address, size_t size, bool heap, u8 attr) {
|
||||
m_address = address;
|
||||
m_size = size;
|
||||
m_heap = heap;
|
||||
m_attr = attr;
|
||||
}
|
||||
|
||||
constexpr KPhysicalAddress GetAddress() const { return m_address; }
|
||||
constexpr size_t GetSize() const { return m_size; }
|
||||
constexpr bool IsHeap() const { return m_heap; }
|
||||
constexpr u8 GetAttribute() const { return m_attr; }
|
||||
|
||||
void Open();
|
||||
void Close();
|
||||
|
|
|
@ -258,7 +258,7 @@ namespace ams::kern::arch::arm64 {
|
|||
|
||||
/* Begin the traversal. */
|
||||
TraversalContext context;
|
||||
TraversalEntry cur_entry = { .phys_addr = Null<KPhysicalAddress>, .block_size = 0, .sw_reserved_bits = 0 };
|
||||
TraversalEntry cur_entry = { .phys_addr = Null<KPhysicalAddress>, .block_size = 0, .sw_reserved_bits = 0, .attr = 0 };
|
||||
bool cur_valid = false;
|
||||
TraversalEntry next_entry;
|
||||
bool next_valid;
|
||||
|
@ -268,7 +268,9 @@ namespace ams::kern::arch::arm64 {
|
|||
|
||||
/* Iterate over entries. */
|
||||
while (true) {
|
||||
if ((!next_valid && !cur_valid) || (next_valid && cur_valid && next_entry.phys_addr == cur_entry.phys_addr + cur_entry.block_size)) {
|
||||
/* NOTE: Nintendo really does check next_entry.attr == (cur_entry.attr != 0)...but attr is always zero as of 18.0.0, and this is "probably" for the new console or debug-only anyway, */
|
||||
/* so we'll implement the weird logic verbatim even though it doesn't match the GetContiguousRange logic. */
|
||||
if ((!next_valid && !cur_valid) || (next_valid && cur_valid && next_entry.phys_addr == cur_entry.phys_addr + cur_entry.block_size && next_entry.attr == (cur_entry.attr ? 1 : 0))) {
|
||||
cur_entry.block_size += next_entry.block_size;
|
||||
} else {
|
||||
if (cur_valid && IsHeapPhysicalAddressForFinalize(cur_entry.phys_addr)) {
|
||||
|
|
|
@ -46,12 +46,14 @@ namespace ams::kern::arch::arm64 {
|
|||
out_entry->block_size = L3BlockSize;
|
||||
}
|
||||
out_entry->sw_reserved_bits = l3_entry->GetSoftwareReservedBits();
|
||||
out_entry->attr = 0;
|
||||
|
||||
return true;
|
||||
} else {
|
||||
out_entry->phys_addr = Null<KPhysicalAddress>;
|
||||
out_entry->block_size = L3BlockSize;
|
||||
out_entry->sw_reserved_bits = 0;
|
||||
out_entry->attr = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -69,6 +71,7 @@ namespace ams::kern::arch::arm64 {
|
|||
out_entry->block_size = L2BlockSize;
|
||||
}
|
||||
out_entry->sw_reserved_bits = l2_entry->GetSoftwareReservedBits();
|
||||
out_entry->attr = 0;
|
||||
|
||||
/* Set the output context. */
|
||||
out_context->l3_entry = nullptr;
|
||||
|
@ -79,6 +82,8 @@ namespace ams::kern::arch::arm64 {
|
|||
out_entry->phys_addr = Null<KPhysicalAddress>;
|
||||
out_entry->block_size = L2BlockSize;
|
||||
out_entry->sw_reserved_bits = 0;
|
||||
out_entry->attr = 0;
|
||||
|
||||
out_context->l3_entry = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
@ -108,6 +113,8 @@ namespace ams::kern::arch::arm64 {
|
|||
out_entry->phys_addr = Null<KPhysicalAddress>;
|
||||
out_entry->block_size = L1BlockSize;
|
||||
out_entry->sw_reserved_bits = 0;
|
||||
out_entry->attr = 0;
|
||||
|
||||
out_context->l2_entry = nullptr;
|
||||
out_context->l3_entry = nullptr;
|
||||
return false;
|
||||
|
@ -119,6 +126,7 @@ namespace ams::kern::arch::arm64 {
|
|||
out_entry->phys_addr = Null<KPhysicalAddress>;
|
||||
out_entry->block_size = L1BlockSize;
|
||||
out_entry->sw_reserved_bits = 0;
|
||||
out_entry->attr = 0;
|
||||
out_context->l1_entry = m_table + m_num_entries;
|
||||
out_context->l2_entry = nullptr;
|
||||
out_context->l3_entry = nullptr;
|
||||
|
@ -220,6 +228,7 @@ namespace ams::kern::arch::arm64 {
|
|||
out_entry->phys_addr = Null<KPhysicalAddress>;
|
||||
out_entry->block_size = L1BlockSize;
|
||||
out_entry->sw_reserved_bits = 0;
|
||||
out_entry->attr = 0;
|
||||
context->l1_entry = m_table + m_num_entries;
|
||||
context->l2_entry = nullptr;
|
||||
context->l3_entry = nullptr;
|
||||
|
|
|
@ -916,7 +916,7 @@ namespace ams::kern {
|
|||
|
||||
/* Begin traversal. */
|
||||
TraversalContext context;
|
||||
TraversalEntry cur_entry = { .phys_addr = Null<KPhysicalAddress>, .block_size = 0, .sw_reserved_bits = 0 };
|
||||
TraversalEntry cur_entry = { .phys_addr = Null<KPhysicalAddress>, .block_size = 0, .sw_reserved_bits = 0, .attr = 0 };
|
||||
bool cur_valid = false;
|
||||
TraversalEntry next_entry;
|
||||
bool next_valid;
|
||||
|
@ -1687,11 +1687,12 @@ namespace ams::kern {
|
|||
|
||||
/* Begin a traversal. */
|
||||
TraversalContext context;
|
||||
TraversalEntry cur_entry = { .phys_addr = Null<KPhysicalAddress>, .block_size = 0, .sw_reserved_bits = 0 };
|
||||
TraversalEntry cur_entry = { .phys_addr = Null<KPhysicalAddress>, .block_size = 0, .sw_reserved_bits = 0, .attr = 0 };
|
||||
R_UNLESS(impl.BeginTraversal(std::addressof(cur_entry), std::addressof(context), address), svc::ResultInvalidCurrentMemory());
|
||||
|
||||
/* Traverse until we have enough size or we aren't contiguous any more. */
|
||||
const KPhysicalAddress phys_address = cur_entry.phys_addr;
|
||||
const u8 entry_attr = cur_entry.attr;
|
||||
size_t contig_size;
|
||||
for (contig_size = cur_entry.block_size - (GetInteger(phys_address) & (cur_entry.block_size - 1)); contig_size < size; contig_size += cur_entry.block_size) {
|
||||
if (!impl.ContinueTraversal(std::addressof(cur_entry), std::addressof(context))) {
|
||||
|
@ -1700,6 +1701,9 @@ namespace ams::kern {
|
|||
if (cur_entry.phys_addr != phys_address + contig_size) {
|
||||
break;
|
||||
}
|
||||
if (cur_entry.attr != entry_attr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Take the minimum size for our region. */
|
||||
|
@ -1713,7 +1717,7 @@ namespace ams::kern {
|
|||
}
|
||||
|
||||
/* The memory is contiguous, so set the output range. */
|
||||
out->Set(phys_address, size, is_heap);
|
||||
out->Set(phys_address, size, is_heap, attr);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue