[Zion] Add a AddressSpaceUnmap syscall to free memory.
This commit is contained in:
parent
e668428d9d
commit
30b6511467
|
@ -74,32 +74,32 @@ void BinaryTree<K, V>::Delete(K key) {
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<BinaryNode> new_child = nullptr;
|
RefPtr<BinaryNode> new_child = nullptr;
|
||||||
if (!node.left) {
|
if (!node->left) {
|
||||||
// No children.
|
// No children.
|
||||||
// Right child only.
|
// Right child only.
|
||||||
new_child = node.right;
|
new_child = node->right;
|
||||||
} else if (!node.right) {
|
} else if (!node->right) {
|
||||||
// Left child only.
|
// Left child only.
|
||||||
new_child = node.left;
|
new_child = node->left;
|
||||||
} else {
|
} else {
|
||||||
// Find Successor.
|
// Find Successor.
|
||||||
auto successor = node.right;
|
auto successor = node->right;
|
||||||
while (successor.left) {
|
while (successor->left) {
|
||||||
successor = successor.left;
|
successor = successor->left;
|
||||||
}
|
}
|
||||||
new_child = successor;
|
new_child = successor;
|
||||||
if (successor != node.right) {
|
if (successor != node->right) {
|
||||||
successor.parent.left = successor.right;
|
successor->parent->left = successor->right;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node == root_) {
|
if (node == root_) {
|
||||||
root_ = new_child;
|
root_ = new_child;
|
||||||
} else {
|
} else {
|
||||||
if (node.parent.right == node) {
|
if (node->parent->right == node) {
|
||||||
node.parent.right = new_child;
|
node->parent->right = new_child;
|
||||||
} else {
|
} else {
|
||||||
node.parent.left = new_child;
|
node->parent->left = new_child;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ add_executable(zion
|
||||||
interrupt/interrupt.cpp
|
interrupt/interrupt.cpp
|
||||||
interrupt/interrupt_enter.s
|
interrupt/interrupt_enter.s
|
||||||
interrupt/timer.cpp
|
interrupt/timer.cpp
|
||||||
|
lib/memory_mapping_tree.cpp
|
||||||
lib/message_queue.cpp
|
lib/message_queue.cpp
|
||||||
loader/init_loader.cpp
|
loader/init_loader.cpp
|
||||||
memory/kernel_heap.cpp
|
memory/kernel_heap.cpp
|
||||||
|
|
|
@ -19,6 +19,8 @@ SYS1(ThreadWait, z_cap_t, thread_cap);
|
||||||
|
|
||||||
SYS4(AddressSpaceMap, z_cap_t, vmas_cap, uint64_t, vmas_offset, z_cap_t,
|
SYS4(AddressSpaceMap, z_cap_t, vmas_cap, uint64_t, vmas_offset, z_cap_t,
|
||||||
vmmo_cap, uint64_t*, vaddr);
|
vmmo_cap, uint64_t*, vaddr);
|
||||||
|
SYS3(AddressSpaceUnmap, z_cap_t, vmas_cap, uint64_t, lower_addr, uint64_t,
|
||||||
|
upper_addr);
|
||||||
|
|
||||||
SYS2(MemoryObjectCreate, uint64_t, size, z_cap_t*, vmmo_cap);
|
SYS2(MemoryObjectCreate, uint64_t, size, z_cap_t*, vmmo_cap);
|
||||||
SYS3(MemoryObjectCreatePhysical, uint64_t, paddr, uint64_t, size, z_cap_t*,
|
SYS3(MemoryObjectCreatePhysical, uint64_t, paddr, uint64_t, size, z_cap_t*,
|
||||||
|
|
|
@ -21,7 +21,7 @@ const uint64_t kZionThreadWait = 0x13;
|
||||||
|
|
||||||
// Memory Calls
|
// Memory Calls
|
||||||
const uint64_t kZionAddressSpaceMap = 0x21;
|
const uint64_t kZionAddressSpaceMap = 0x21;
|
||||||
const uint64_t kZionAddressSpaceUnMap = 0x21;
|
const uint64_t kZionAddressSpaceUnmap = 0x22;
|
||||||
|
|
||||||
const uint64_t kZionMemoryObjectCreate = 0x30;
|
const uint64_t kZionMemoryObjectCreate = 0x30;
|
||||||
const uint64_t kZionMemoryObjectCreatePhysical = 0x31;
|
const uint64_t kZionMemoryObjectCreatePhysical = 0x31;
|
||||||
|
|
|
@ -28,9 +28,32 @@ glcr::ErrorCode MemoryMappingTree::AddInMemoryObject(
|
||||||
return glcr::OK;
|
return glcr::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
glcr::ErrorCode FreeMemoryRange(uint64_t vaddr_base, uint64_t vaddr_limit) {
|
glcr::ErrorCode MemoryMappingTree::FreeMemoryRange(uint64_t vaddr_base,
|
||||||
dbgln("Unhandled free memory range!");
|
uint64_t vaddr_limit) {
|
||||||
return glcr::OK;
|
if (vaddr_limit <= vaddr_base) {
|
||||||
|
return glcr::INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
auto predecessor_or = mapping_tree_.Predecessor(vaddr_base);
|
||||||
|
if (predecessor_or && predecessor_or.value().get().vaddr_limit > vaddr_base) {
|
||||||
|
return glcr::FAILED_PRECONDITION;
|
||||||
|
}
|
||||||
|
auto last_predecessor_or = mapping_tree_.Predecessor(vaddr_limit);
|
||||||
|
if (last_predecessor_or &&
|
||||||
|
last_predecessor_or.value().get().vaddr_limit > vaddr_limit) {
|
||||||
|
return glcr::FAILED_PRECONDITION;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto find_or = mapping_tree_.Find(vaddr_base);
|
||||||
|
if (find_or) {
|
||||||
|
mapping_tree_.Delete(vaddr_base);
|
||||||
|
}
|
||||||
|
while (true) {
|
||||||
|
auto successor_or = mapping_tree_.Successor(vaddr_base);
|
||||||
|
if (!successor_or || successor_or.value().get().vaddr_base >= vaddr_limit) {
|
||||||
|
return glcr::OK;
|
||||||
|
}
|
||||||
|
mapping_tree_.Delete(successor_or.value().get().vaddr_base);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glcr::ErrorOr<uint64_t> MemoryMappingTree::GetPhysicalPageAtVaddr(
|
glcr::ErrorOr<uint64_t> MemoryMappingTree::GetPhysicalPageAtVaddr(
|
||||||
|
|
|
@ -76,6 +76,11 @@ class AddressSpace : public KernelObject {
|
||||||
[[nodiscard]] glcr::ErrorOr<uint64_t> MapInMemoryObject(
|
[[nodiscard]] glcr::ErrorOr<uint64_t> MapInMemoryObject(
|
||||||
const glcr::RefPtr<MemoryObject>& mem_obj);
|
const glcr::RefPtr<MemoryObject>& mem_obj);
|
||||||
|
|
||||||
|
[[nodiscard]] glcr::ErrorCode FreeAddressRange(uint64_t vaddr_base,
|
||||||
|
uint64_t vaddr_limit) {
|
||||||
|
return mapping_tree_.FreeMemoryRange(vaddr_base, vaddr_limit);
|
||||||
|
}
|
||||||
|
|
||||||
// Kernel Mappings.
|
// Kernel Mappings.
|
||||||
uint64_t AllocateKernelStack();
|
uint64_t AllocateKernelStack();
|
||||||
|
|
||||||
|
|
|
@ -15,10 +15,19 @@ z_err_t AddressSpaceMap(ZAddressSpaceMapReq* req) {
|
||||||
|
|
||||||
// FIXME: Validation necessary.
|
// FIXME: Validation necessary.
|
||||||
if (req->vmas_offset != 0) {
|
if (req->vmas_offset != 0) {
|
||||||
vmas->MapInMemoryObject(req->vmas_offset, vmmo);
|
RET_ERR(vmas->MapInMemoryObject(req->vmas_offset, vmmo));
|
||||||
*req->vaddr = req->vmas_offset;
|
*req->vaddr = req->vmas_offset;
|
||||||
} else {
|
} else {
|
||||||
*req->vaddr = vmas->MapInMemoryObject(vmmo);
|
ASSIGN_OR_RETURN(*req->vaddr, vmas->MapInMemoryObject(vmmo));
|
||||||
}
|
}
|
||||||
return glcr::OK;
|
return glcr::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
z_err_t AddressSpaceUnmap(ZAddressSpaceUnmapReq* req) {
|
||||||
|
auto& curr_proc = gScheduler->CurrentProcess();
|
||||||
|
auto vmas_cap = curr_proc.GetCapability(req->vmas_cap);
|
||||||
|
RET_ERR(ValidateCapability<AddressSpace>(vmas_cap, kZionPerm_Write));
|
||||||
|
|
||||||
|
auto vmas = vmas_cap->obj<AddressSpace>();
|
||||||
|
return vmas->FreeAddressRange(req->lower_addr, req->upper_addr);
|
||||||
|
}
|
||||||
|
|
|
@ -3,3 +3,4 @@
|
||||||
#include "include/zcall.h"
|
#include "include/zcall.h"
|
||||||
|
|
||||||
z_err_t AddressSpaceMap(ZAddressSpaceMapReq* req);
|
z_err_t AddressSpaceMap(ZAddressSpaceMapReq* req);
|
||||||
|
z_err_t AddressSpaceUnmap(ZAddressSpaceUnmapReq* req);
|
||||||
|
|
|
@ -60,6 +60,7 @@ extern "C" z_err_t SyscallHandler(uint64_t call_id, void* req) {
|
||||||
CASE(ThreadWait);
|
CASE(ThreadWait);
|
||||||
// syscall/address_space.h
|
// syscall/address_space.h
|
||||||
CASE(AddressSpaceMap);
|
CASE(AddressSpaceMap);
|
||||||
|
CASE(AddressSpaceUnmap);
|
||||||
// syscall/memory_object.h
|
// syscall/memory_object.h
|
||||||
CASE(MemoryObjectCreate);
|
CASE(MemoryObjectCreate);
|
||||||
CASE(MemoryObjectCreatePhysical);
|
CASE(MemoryObjectCreatePhysical);
|
||||||
|
|
Loading…
Reference in New Issue