[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;
|
||||
if (!node.left) {
|
||||
if (!node->left) {
|
||||
// No children.
|
||||
// Right child only.
|
||||
new_child = node.right;
|
||||
} else if (!node.right) {
|
||||
new_child = node->right;
|
||||
} else if (!node->right) {
|
||||
// Left child only.
|
||||
new_child = node.left;
|
||||
new_child = node->left;
|
||||
} else {
|
||||
// Find Successor.
|
||||
auto successor = node.right;
|
||||
while (successor.left) {
|
||||
successor = successor.left;
|
||||
auto successor = node->right;
|
||||
while (successor->left) {
|
||||
successor = successor->left;
|
||||
}
|
||||
new_child = successor;
|
||||
if (successor != node.right) {
|
||||
successor.parent.left = successor.right;
|
||||
if (successor != node->right) {
|
||||
successor->parent->left = successor->right;
|
||||
}
|
||||
}
|
||||
|
||||
if (node == root_) {
|
||||
root_ = new_child;
|
||||
} else {
|
||||
if (node.parent.right == node) {
|
||||
node.parent.right = new_child;
|
||||
if (node->parent->right == node) {
|
||||
node->parent->right = new_child;
|
||||
} else {
|
||||
node.parent.left = new_child;
|
||||
node->parent->left = new_child;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ add_executable(zion
|
|||
interrupt/interrupt.cpp
|
||||
interrupt/interrupt_enter.s
|
||||
interrupt/timer.cpp
|
||||
lib/memory_mapping_tree.cpp
|
||||
lib/message_queue.cpp
|
||||
loader/init_loader.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,
|
||||
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);
|
||||
SYS3(MemoryObjectCreatePhysical, uint64_t, paddr, uint64_t, size, z_cap_t*,
|
||||
|
|
|
@ -21,7 +21,7 @@ const uint64_t kZionThreadWait = 0x13;
|
|||
|
||||
// Memory Calls
|
||||
const uint64_t kZionAddressSpaceMap = 0x21;
|
||||
const uint64_t kZionAddressSpaceUnMap = 0x21;
|
||||
const uint64_t kZionAddressSpaceUnmap = 0x22;
|
||||
|
||||
const uint64_t kZionMemoryObjectCreate = 0x30;
|
||||
const uint64_t kZionMemoryObjectCreatePhysical = 0x31;
|
||||
|
|
|
@ -28,9 +28,32 @@ glcr::ErrorCode MemoryMappingTree::AddInMemoryObject(
|
|||
return glcr::OK;
|
||||
}
|
||||
|
||||
glcr::ErrorCode FreeMemoryRange(uint64_t vaddr_base, uint64_t vaddr_limit) {
|
||||
dbgln("Unhandled free memory range!");
|
||||
return glcr::OK;
|
||||
glcr::ErrorCode MemoryMappingTree::FreeMemoryRange(uint64_t vaddr_base,
|
||||
uint64_t vaddr_limit) {
|
||||
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(
|
||||
|
|
|
@ -76,6 +76,11 @@ class AddressSpace : public KernelObject {
|
|||
[[nodiscard]] glcr::ErrorOr<uint64_t> MapInMemoryObject(
|
||||
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.
|
||||
uint64_t AllocateKernelStack();
|
||||
|
||||
|
|
|
@ -15,10 +15,19 @@ z_err_t AddressSpaceMap(ZAddressSpaceMapReq* req) {
|
|||
|
||||
// FIXME: Validation necessary.
|
||||
if (req->vmas_offset != 0) {
|
||||
vmas->MapInMemoryObject(req->vmas_offset, vmmo);
|
||||
RET_ERR(vmas->MapInMemoryObject(req->vmas_offset, vmmo));
|
||||
*req->vaddr = req->vmas_offset;
|
||||
} else {
|
||||
*req->vaddr = vmas->MapInMemoryObject(vmmo);
|
||||
ASSIGN_OR_RETURN(*req->vaddr, vmas->MapInMemoryObject(vmmo));
|
||||
}
|
||||
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"
|
||||
|
||||
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);
|
||||
// syscall/address_space.h
|
||||
CASE(AddressSpaceMap);
|
||||
CASE(AddressSpaceUnmap);
|
||||
// syscall/memory_object.h
|
||||
CASE(MemoryObjectCreate);
|
||||
CASE(MemoryObjectCreatePhysical);
|
||||
|
|
Loading…
Reference in New Issue