mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-12-22 02:12:06 +00:00
kern: update KMemoryRegion to store last address rather than size
This commit is contained in:
parent
5da6b60008
commit
aac8af8bf5
3 changed files with 36 additions and 37 deletions
|
@ -29,7 +29,7 @@ namespace ams::kern {
|
||||||
private:
|
private:
|
||||||
uintptr_t address;
|
uintptr_t address;
|
||||||
uintptr_t pair_address;
|
uintptr_t pair_address;
|
||||||
size_t region_size;
|
uintptr_t last_address;
|
||||||
u32 attributes;
|
u32 attributes;
|
||||||
u32 type_id;
|
u32 type_id;
|
||||||
public:
|
public:
|
||||||
|
@ -43,18 +43,18 @@ namespace ams::kern {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
constexpr ALWAYS_INLINE KMemoryRegion() : address(0), pair_address(0), region_size(0), attributes(0), type_id(0) { /* ... */ }
|
constexpr ALWAYS_INLINE KMemoryRegion() : address(0), pair_address(0), last_address(0), attributes(0), type_id(0) { /* ... */ }
|
||||||
constexpr ALWAYS_INLINE KMemoryRegion(uintptr_t a, size_t rs, uintptr_t p, u32 r, u32 t) :
|
constexpr ALWAYS_INLINE KMemoryRegion(uintptr_t a, size_t la, uintptr_t p, u32 r, u32 t) :
|
||||||
address(a), pair_address(p), region_size(rs), attributes(r), type_id(t)
|
address(a), pair_address(p), last_address(la), attributes(r), type_id(t)
|
||||||
{
|
{
|
||||||
/* ... */
|
/* ... */
|
||||||
}
|
}
|
||||||
constexpr ALWAYS_INLINE KMemoryRegion(uintptr_t a, size_t rs, u32 r, u32 t) : KMemoryRegion(a, rs, std::numeric_limits<uintptr_t>::max(), r, t) { /* ... */ }
|
constexpr ALWAYS_INLINE KMemoryRegion(uintptr_t a, size_t la, u32 r, u32 t) : KMemoryRegion(a, la, std::numeric_limits<uintptr_t>::max(), r, t) { /* ... */ }
|
||||||
private:
|
private:
|
||||||
constexpr ALWAYS_INLINE void Reset(uintptr_t a, uintptr_t rs, uintptr_t p, u32 r, u32 t) {
|
constexpr ALWAYS_INLINE void Reset(uintptr_t a, uintptr_t la, uintptr_t p, u32 r, u32 t) {
|
||||||
this->address = a;
|
this->address = a;
|
||||||
this->pair_address = p;
|
this->pair_address = p;
|
||||||
this->region_size = rs;
|
this->last_address = la;
|
||||||
this->attributes = r;
|
this->attributes = r;
|
||||||
this->type_id = t;
|
this->type_id = t;
|
||||||
}
|
}
|
||||||
|
@ -67,16 +67,16 @@ namespace ams::kern {
|
||||||
return this->pair_address;
|
return this->pair_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE size_t GetSize() const {
|
constexpr ALWAYS_INLINE uintptr_t GetLastAddress() const {
|
||||||
return this->region_size;
|
return this->last_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE uintptr_t GetEndAddress() const {
|
constexpr ALWAYS_INLINE uintptr_t GetEndAddress() const {
|
||||||
return this->GetAddress() + this->GetSize();
|
return this->GetLastAddress() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE uintptr_t GetLastAddress() const {
|
constexpr ALWAYS_INLINE size_t GetSize() const {
|
||||||
return this->GetEndAddress() - 1;
|
return this->GetEndAddress() - this->GetAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE u32 GetAttributes() const {
|
constexpr ALWAYS_INLINE u32 GetAttributes() const {
|
||||||
|
@ -130,17 +130,17 @@ namespace ams::kern {
|
||||||
return this->first_region->GetAddress();
|
return this->first_region->GetAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr ALWAYS_INLINE uintptr_t GetLastAddress() const {
|
||||||
|
return this->last_region->GetLastAddress();
|
||||||
|
}
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE uintptr_t GetEndAddress() const {
|
constexpr ALWAYS_INLINE uintptr_t GetEndAddress() const {
|
||||||
return this->last_region->GetEndAddress();
|
return this->GetLastAddress() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE size_t GetSize() const {
|
constexpr ALWAYS_INLINE size_t GetSize() const {
|
||||||
return this->GetEndAddress() - this->GetAddress();
|
return this->GetEndAddress() - this->GetAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE uintptr_t GetLastAddress() const {
|
|
||||||
return this->GetEndAddress() - 1;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
using TreeType = util::IntrusiveRedBlackTreeBaseTraits<KMemoryRegion>::TreeType<KMemoryRegion>;
|
using TreeType = util::IntrusiveRedBlackTreeBaseTraits<KMemoryRegion>::TreeType<KMemoryRegion>;
|
||||||
|
@ -160,7 +160,7 @@ namespace ams::kern {
|
||||||
constexpr ALWAYS_INLINE KMemoryRegionTree() : tree() { /* ... */ }
|
constexpr ALWAYS_INLINE KMemoryRegionTree() : tree() { /* ... */ }
|
||||||
public:
|
public:
|
||||||
KMemoryRegion *FindModifiable(uintptr_t address) {
|
KMemoryRegion *FindModifiable(uintptr_t address) {
|
||||||
if (auto it = this->find(KMemoryRegion(address, 1, 0, 0)); it != this->end()) {
|
if (auto it = this->find(KMemoryRegion(address, address, 0, 0)); it != this->end()) {
|
||||||
return std::addressof(*it);
|
return std::addressof(*it);
|
||||||
} else {
|
} else {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -168,7 +168,7 @@ namespace ams::kern {
|
||||||
}
|
}
|
||||||
|
|
||||||
const KMemoryRegion *Find(uintptr_t address) const {
|
const KMemoryRegion *Find(uintptr_t address) const {
|
||||||
if (auto it = this->find(KMemoryRegion(address, 1, 0, 0)); it != this->cend()) {
|
if (auto it = this->find(KMemoryRegion(address, address, 0, 0)); it != this->cend()) {
|
||||||
return std::addressof(*it);
|
return std::addressof(*it);
|
||||||
} else {
|
} else {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -234,7 +234,7 @@ namespace ams::kern {
|
||||||
return extents;
|
return extents;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
NOINLINE void InsertDirectly(uintptr_t address, size_t size, u32 attr = 0, u32 type_id = 0);
|
NOINLINE void InsertDirectly(uintptr_t address, uintptr_t last_address, u32 attr = 0, u32 type_id = 0);
|
||||||
NOINLINE bool Insert(uintptr_t address, size_t size, u32 type_id, u32 new_attr = 0, u32 old_attr = 0);
|
NOINLINE bool Insert(uintptr_t address, size_t size, u32 type_id, u32 new_attr = 0, u32 old_attr = 0);
|
||||||
|
|
||||||
NOINLINE KVirtualAddress GetRandomAlignedRegion(size_t size, size_t alignment, u32 type_id);
|
NOINLINE KVirtualAddress GetRandomAlignedRegion(size_t size, size_t alignment, u32 type_id);
|
||||||
|
|
|
@ -40,8 +40,6 @@ namespace ams::kern {
|
||||||
new (region) KMemoryRegion(std::forward<Args>(args)...);
|
new (region) KMemoryRegion(std::forward<Args>(args)...);
|
||||||
|
|
||||||
return region;
|
return region;
|
||||||
|
|
||||||
return &this->region_heap[this->num_regions++];
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -55,8 +53,8 @@ namespace ams::kern {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void KMemoryRegionTree::InsertDirectly(uintptr_t address, size_t size, u32 attr, u32 type_id) {
|
void KMemoryRegionTree::InsertDirectly(uintptr_t address, uintptr_t last_address, u32 attr, u32 type_id) {
|
||||||
this->insert(*AllocateRegion(address, size, attr, type_id));
|
this->insert(*AllocateRegion(address, last_address, attr, type_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KMemoryRegionTree::Insert(uintptr_t address, size_t size, u32 type_id, u32 new_attr, u32 old_attr) {
|
bool KMemoryRegionTree::Insert(uintptr_t address, size_t size, u32 type_id, u32 new_attr, u32 old_attr) {
|
||||||
|
@ -82,9 +80,7 @@ namespace ams::kern {
|
||||||
|
|
||||||
/* Cache information from the region before we remove it. */
|
/* Cache information from the region before we remove it. */
|
||||||
const uintptr_t old_address = found->GetAddress();
|
const uintptr_t old_address = found->GetAddress();
|
||||||
const size_t old_size = found->GetSize();
|
const uintptr_t old_last = found->GetLastAddress();
|
||||||
const uintptr_t old_end = old_address + old_size;
|
|
||||||
const uintptr_t old_last = old_end - 1;
|
|
||||||
const uintptr_t old_pair = found->GetPairAddress();
|
const uintptr_t old_pair = found->GetPairAddress();
|
||||||
const u32 old_type = found->GetType();
|
const u32 old_type = found->GetType();
|
||||||
|
|
||||||
|
@ -92,24 +88,24 @@ namespace ams::kern {
|
||||||
this->erase(this->iterator_to(*found));
|
this->erase(this->iterator_to(*found));
|
||||||
|
|
||||||
/* Insert the new region into the tree. */
|
/* Insert the new region into the tree. */
|
||||||
const uintptr_t new_pair = (old_pair != std::numeric_limits<uintptr_t>::max()) ? old_pair + (address - old_address) : old_pair;
|
|
||||||
if (old_address == address) {
|
if (old_address == address) {
|
||||||
/* Reuse the old object for the new region, if we can. */
|
/* Reuse the old object for the new region, if we can. */
|
||||||
found->Reset(address, size, new_pair, new_attr, type_id);
|
found->Reset(address, inserted_region_last, old_pair, new_attr, type_id);
|
||||||
this->insert(*found);
|
this->insert(*found);
|
||||||
} else {
|
} else {
|
||||||
/* If we can't re-use, adjust the old region. */
|
/* If we can't re-use, adjust the old region. */
|
||||||
found->Reset(old_address, address - old_address, old_pair, old_attr, old_type);
|
found->Reset(old_address, address - 1, old_pair, old_attr, old_type);
|
||||||
this->insert(*found);
|
this->insert(*found);
|
||||||
|
|
||||||
/* Insert a new region for the split. */
|
/* Insert a new region for the split. */
|
||||||
this->insert(*AllocateRegion(address, size, new_pair, new_attr, type_id));
|
const uintptr_t new_pair = (old_pair != std::numeric_limits<uintptr_t>::max()) ? old_pair + (address - old_address) : old_pair;
|
||||||
|
this->insert(*AllocateRegion(address, inserted_region_last, new_pair, new_attr, type_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we need to insert a region after the region, do so. */
|
/* If we need to insert a region after the region, do so. */
|
||||||
if (old_last != inserted_region_last) {
|
if (old_last != inserted_region_last) {
|
||||||
const uintptr_t after_pair = (old_pair != std::numeric_limits<uintptr_t>::max()) ? old_pair + (inserted_region_end - old_address) : old_pair;
|
const uintptr_t after_pair = (old_pair != std::numeric_limits<uintptr_t>::max()) ? old_pair + (inserted_region_end - old_address) : old_pair;
|
||||||
this->insert(*AllocateRegion(inserted_region_end, old_end - inserted_region_end, after_pair, old_attr, old_type));
|
this->insert(*AllocateRegion(inserted_region_end, old_last, after_pair, old_attr, old_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -125,8 +121,11 @@ namespace ams::kern {
|
||||||
const uintptr_t first_address = extents.GetAddress();
|
const uintptr_t first_address = extents.GetAddress();
|
||||||
const uintptr_t last_address = extents.GetLastAddress();
|
const uintptr_t last_address = extents.GetLastAddress();
|
||||||
|
|
||||||
|
const uintptr_t first_index = first_address / alignment;
|
||||||
|
const uintptr_t last_index = last_address / alignment;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
const uintptr_t candidate = util::AlignDown(KSystemControl::Init::GenerateRandomRange(first_address, last_address), alignment);
|
const uintptr_t candidate = KSystemControl::Init::GenerateRandomRange(first_index, last_index) * alignment;
|
||||||
|
|
||||||
/* Ensure that the candidate doesn't overflow with the size. */
|
/* Ensure that the candidate doesn't overflow with the size. */
|
||||||
if (!(candidate < candidate + size)) {
|
if (!(candidate < candidate + size)) {
|
||||||
|
@ -157,13 +156,13 @@ namespace ams::kern {
|
||||||
/* Initialize linear trees. */
|
/* Initialize linear trees. */
|
||||||
for (auto ®ion : GetPhysicalMemoryRegionTree()) {
|
for (auto ®ion : GetPhysicalMemoryRegionTree()) {
|
||||||
if (region.HasTypeAttribute(KMemoryRegionAttr_LinearMapped)) {
|
if (region.HasTypeAttribute(KMemoryRegionAttr_LinearMapped)) {
|
||||||
GetPhysicalLinearMemoryRegionTree().InsertDirectly(region.GetAddress(), region.GetSize(), region.GetAttributes(), region.GetType());
|
GetPhysicalLinearMemoryRegionTree().InsertDirectly(region.GetAddress(), region.GetLastAddress(), region.GetAttributes(), region.GetType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto ®ion : GetVirtualMemoryRegionTree()) {
|
for (auto ®ion : GetVirtualMemoryRegionTree()) {
|
||||||
if (region.IsDerivedFrom(KMemoryRegionType_Dram)) {
|
if (region.IsDerivedFrom(KMemoryRegionType_Dram)) {
|
||||||
GetVirtualLinearMemoryRegionTree().InsertDirectly(region.GetAddress(), region.GetSize(), region.GetAttributes(), region.GetType());
|
GetVirtualLinearMemoryRegionTree().InsertDirectly(region.GetAddress(), region.GetLastAddress(), region.GetAttributes(), region.GetType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,10 +139,10 @@ namespace ams::kern::init {
|
||||||
InitializeSlabResourceCounts();
|
InitializeSlabResourceCounts();
|
||||||
|
|
||||||
/* Insert the root region for the virtual memory tree, from which all other regions will derive. */
|
/* Insert the root region for the virtual memory tree, from which all other regions will derive. */
|
||||||
KMemoryLayout::GetVirtualMemoryRegionTree().InsertDirectly(KernelVirtualAddressSpaceBase, KernelVirtualAddressSpaceSize);
|
KMemoryLayout::GetVirtualMemoryRegionTree().InsertDirectly(KernelVirtualAddressSpaceBase, KernelVirtualAddressSpaceBase + KernelVirtualAddressSpaceSize - 1);
|
||||||
|
|
||||||
/* Insert the root region for the physical memory tree, from which all other regions will derive. */
|
/* Insert the root region for the physical memory tree, from which all other regions will derive. */
|
||||||
KMemoryLayout::GetPhysicalMemoryRegionTree().InsertDirectly(KernelPhysicalAddressSpaceBase, KernelPhysicalAddressSpaceSize);
|
KMemoryLayout::GetPhysicalMemoryRegionTree().InsertDirectly(KernelPhysicalAddressSpaceBase, KernelPhysicalAddressSpaceBase + KernelPhysicalAddressSpaceSize - 1);
|
||||||
|
|
||||||
/* Save start and end for ease of use. */
|
/* Save start and end for ease of use. */
|
||||||
const uintptr_t code_start_virt_addr = reinterpret_cast<uintptr_t>(_start);
|
const uintptr_t code_start_virt_addr = reinterpret_cast<uintptr_t>(_start);
|
||||||
|
|
Loading…
Reference in a new issue