diff --git a/src/hlib/include/syscalls.h b/src/hlib/include/syscalls.h index 2025b24..84a94db 100644 --- a/src/hlib/include/syscalls.h +++ b/src/hlib/include/syscalls.h @@ -29,6 +29,7 @@ SYS_AWAIT = 21, SYS_GET_PHYSICAL = 22, SYS_FORK = 23, + SYS_FREE_PAGE = 24, } SyscallIds; extern uint32_t getFunction(uint32_t module, char *name); diff --git a/src/hlib/include/syscalls.h b/src/hlib/include/syscalls.h index 2025b24..84a94db 100644 --- a/src/hlib/include/syscalls.h +++ b/src/hlib/include/syscalls.h @@ -29,6 +29,7 @@ SYS_AWAIT = 21, SYS_GET_PHYSICAL = 22, SYS_FORK = 23, + SYS_FREE_PAGE = 24, } SyscallIds; extern uint32_t getFunction(uint32_t module, char *name); diff --git a/src/hlib/main.c b/src/hlib/main.c index 7775d13..b5cae5f 100644 --- a/src/hlib/main.c +++ b/src/hlib/main.c @@ -53,7 +53,9 @@ void *getPagesCount(uint32_t count) { return requestMemory(count, NULL, NULL); } -void freePage(void *location) {} +void freePage(void *location) { + syscall(SYS_FREE_PAGE, U32(location), 0, 0, 0); +} void memset(void *_target, uint8_t byte, uint32_t size) { uint8_t *target = _target; diff --git a/src/hlib/include/syscalls.h b/src/hlib/include/syscalls.h index 2025b24..84a94db 100644 --- a/src/hlib/include/syscalls.h +++ b/src/hlib/include/syscalls.h @@ -29,6 +29,7 @@ SYS_AWAIT = 21, SYS_GET_PHYSICAL = 22, SYS_FORK = 23, + SYS_FREE_PAGE = 24, } SyscallIds; extern uint32_t getFunction(uint32_t module, char *name); diff --git a/src/hlib/main.c b/src/hlib/main.c index 7775d13..b5cae5f 100644 --- a/src/hlib/main.c +++ b/src/hlib/main.c @@ -53,7 +53,9 @@ void *getPagesCount(uint32_t count) { return requestMemory(count, NULL, NULL); } -void freePage(void *location) {} +void freePage(void *location) { + syscall(SYS_FREE_PAGE, U32(location), 0, 0, 0); +} void memset(void *_target, uint8_t byte, uint32_t size) { uint8_t *target = _target; diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index 5f96d55..ea99a4d 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -45,6 +45,8 @@ extern void freePage(void *pageAddress); extern void freePhysicalPage(uint32_t pageId); extern void unmapPage(void *pageAddress); +extern void unmapPageFrom(PagingInfo *info, void *address); +extern void giveUpPage(PagingInfo *info, uint32_t pageId); extern void free(void *address); diff --git a/src/hlib/include/syscalls.h b/src/hlib/include/syscalls.h index 2025b24..84a94db 100644 --- a/src/hlib/include/syscalls.h +++ b/src/hlib/include/syscalls.h @@ -29,6 +29,7 @@ SYS_AWAIT = 21, SYS_GET_PHYSICAL = 22, SYS_FORK = 23, + SYS_FREE_PAGE = 24, } SyscallIds; extern uint32_t getFunction(uint32_t module, char *name); diff --git a/src/hlib/main.c b/src/hlib/main.c index 7775d13..b5cae5f 100644 --- a/src/hlib/main.c +++ b/src/hlib/main.c @@ -53,7 +53,9 @@ void *getPagesCount(uint32_t count) { return requestMemory(count, NULL, NULL); } -void freePage(void *location) {} +void freePage(void *location) { + syscall(SYS_FREE_PAGE, U32(location), 0, 0, 0); +} void memset(void *_target, uint8_t byte, uint32_t size) { uint8_t *target = _target; diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index 5f96d55..ea99a4d 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -45,6 +45,8 @@ extern void freePage(void *pageAddress); extern void freePhysicalPage(uint32_t pageId); extern void unmapPage(void *pageAddress); +extern void unmapPageFrom(PagingInfo *info, void *address); +extern void giveUpPage(PagingInfo *info, uint32_t pageId); extern void free(void *address); diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index 396839e..d330027 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -240,6 +240,30 @@ } while (info->isPageConnectedToNext[coarse] & fineBit); } +void giveUpPage(PagingInfo *info, uint32_t pageId) { + uint32_t coarse, fine, fineBit; + do { + { + // mark physical page as free + void *physical = getPhysicalAddress(info->pageDirectory, ADDRESS(pageId)); + uint32_t physicalId = PAGE_ID(physical); + uint32_t coarse = physicalId / 32; + uint32_t fine = physicalId % 32; + uint32_t fineBit = 1 << fine; + markPageFree(kernelPhysicalPages, coarse, fine, fineBit); + } + + // mark virtual page as free + coarse = pageId / 32; + fine = pageId % 32; + fineBit = 1 << fine; + markPageFree(info, coarse, fine, fineBit); + unmapSinglePageFrom(info, ADDRESS(pageId)); + pageId++; + } while (info->isPageConnectedToNext[coarse] & fineBit); + +} + void unmapPage(void *pageAddress) { unmapPageFrom(kernelVirtualPages, pageAddress); } diff --git a/src/hlib/include/syscalls.h b/src/hlib/include/syscalls.h index 2025b24..84a94db 100644 --- a/src/hlib/include/syscalls.h +++ b/src/hlib/include/syscalls.h @@ -29,6 +29,7 @@ SYS_AWAIT = 21, SYS_GET_PHYSICAL = 22, SYS_FORK = 23, + SYS_FREE_PAGE = 24, } SyscallIds; extern uint32_t getFunction(uint32_t module, char *name); diff --git a/src/hlib/main.c b/src/hlib/main.c index 7775d13..b5cae5f 100644 --- a/src/hlib/main.c +++ b/src/hlib/main.c @@ -53,7 +53,9 @@ void *getPagesCount(uint32_t count) { return requestMemory(count, NULL, NULL); } -void freePage(void *location) {} +void freePage(void *location) { + syscall(SYS_FREE_PAGE, U32(location), 0, 0, 0); +} void memset(void *_target, uint8_t byte, uint32_t size) { uint8_t *target = _target; diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index 5f96d55..ea99a4d 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -45,6 +45,8 @@ extern void freePage(void *pageAddress); extern void freePhysicalPage(uint32_t pageId); extern void unmapPage(void *pageAddress); +extern void unmapPageFrom(PagingInfo *info, void *address); +extern void giveUpPage(PagingInfo *info, uint32_t pageId); extern void free(void *address); diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index 396839e..d330027 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -240,6 +240,30 @@ } while (info->isPageConnectedToNext[coarse] & fineBit); } +void giveUpPage(PagingInfo *info, uint32_t pageId) { + uint32_t coarse, fine, fineBit; + do { + { + // mark physical page as free + void *physical = getPhysicalAddress(info->pageDirectory, ADDRESS(pageId)); + uint32_t physicalId = PAGE_ID(physical); + uint32_t coarse = physicalId / 32; + uint32_t fine = physicalId % 32; + uint32_t fineBit = 1 << fine; + markPageFree(kernelPhysicalPages, coarse, fine, fineBit); + } + + // mark virtual page as free + coarse = pageId / 32; + fine = pageId % 32; + fineBit = 1 << fine; + markPageFree(info, coarse, fine, fineBit); + unmapSinglePageFrom(info, ADDRESS(pageId)); + pageId++; + } while (info->isPageConnectedToNext[coarse] & fineBit); + +} + void unmapPage(void *pageAddress) { unmapPageFrom(kernelVirtualPages, pageAddress); } diff --git a/src/kernel/service/memorySyscalls.c b/src/kernel/service/memorySyscalls.c index a7c2ab2..096b67e 100644 --- a/src/kernel/service/memorySyscalls.c +++ b/src/kernel/service/memorySyscalls.c @@ -39,3 +39,10 @@ call->returnValue = U32(getPhysicalAddress( service->pagingInfo.pageDirectory, PTR(call->parameters[0]))); } + +void handleFreeSyscall(Syscall *call) { + Service *service = call->service; + uint32_t address = call->parameters[0]; + uint32_t virtualPageId = PAGE_ID(address); + giveUpPage(&service->pagingInfo, virtualPageId); +} \ No newline at end of file diff --git a/src/hlib/include/syscalls.h b/src/hlib/include/syscalls.h index 2025b24..84a94db 100644 --- a/src/hlib/include/syscalls.h +++ b/src/hlib/include/syscalls.h @@ -29,6 +29,7 @@ SYS_AWAIT = 21, SYS_GET_PHYSICAL = 22, SYS_FORK = 23, + SYS_FREE_PAGE = 24, } SyscallIds; extern uint32_t getFunction(uint32_t module, char *name); diff --git a/src/hlib/main.c b/src/hlib/main.c index 7775d13..b5cae5f 100644 --- a/src/hlib/main.c +++ b/src/hlib/main.c @@ -53,7 +53,9 @@ void *getPagesCount(uint32_t count) { return requestMemory(count, NULL, NULL); } -void freePage(void *location) {} +void freePage(void *location) { + syscall(SYS_FREE_PAGE, U32(location), 0, 0, 0); +} void memset(void *_target, uint8_t byte, uint32_t size) { uint8_t *target = _target; diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index 5f96d55..ea99a4d 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -45,6 +45,8 @@ extern void freePage(void *pageAddress); extern void freePhysicalPage(uint32_t pageId); extern void unmapPage(void *pageAddress); +extern void unmapPageFrom(PagingInfo *info, void *address); +extern void giveUpPage(PagingInfo *info, uint32_t pageId); extern void free(void *address); diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index 396839e..d330027 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -240,6 +240,30 @@ } while (info->isPageConnectedToNext[coarse] & fineBit); } +void giveUpPage(PagingInfo *info, uint32_t pageId) { + uint32_t coarse, fine, fineBit; + do { + { + // mark physical page as free + void *physical = getPhysicalAddress(info->pageDirectory, ADDRESS(pageId)); + uint32_t physicalId = PAGE_ID(physical); + uint32_t coarse = physicalId / 32; + uint32_t fine = physicalId % 32; + uint32_t fineBit = 1 << fine; + markPageFree(kernelPhysicalPages, coarse, fine, fineBit); + } + + // mark virtual page as free + coarse = pageId / 32; + fine = pageId % 32; + fineBit = 1 << fine; + markPageFree(info, coarse, fine, fineBit); + unmapSinglePageFrom(info, ADDRESS(pageId)); + pageId++; + } while (info->isPageConnectedToNext[coarse] & fineBit); + +} + void unmapPage(void *pageAddress) { unmapPageFrom(kernelVirtualPages, pageAddress); } diff --git a/src/kernel/service/memorySyscalls.c b/src/kernel/service/memorySyscalls.c index a7c2ab2..096b67e 100644 --- a/src/kernel/service/memorySyscalls.c +++ b/src/kernel/service/memorySyscalls.c @@ -39,3 +39,10 @@ call->returnValue = U32(getPhysicalAddress( service->pagingInfo.pageDirectory, PTR(call->parameters[0]))); } + +void handleFreeSyscall(Syscall *call) { + Service *service = call->service; + uint32_t address = call->parameters[0]; + uint32_t virtualPageId = PAGE_ID(address); + giveUpPage(&service->pagingInfo, virtualPageId); +} \ No newline at end of file diff --git a/src/kernel/syscalls/syscall.c b/src/kernel/syscalls/syscall.c index 7a86b12..975da3d 100644 --- a/src/kernel/syscalls/syscall.c +++ b/src/kernel/syscalls/syscall.c @@ -80,6 +80,7 @@ extern uintptr_t handleAwaitSyscall; extern uintptr_t handleGetPhysicalSyscall; extern uintptr_t handleForkSyscall; +extern uintptr_t handleFreeSyscall; void (*syscallHandlers[])(Syscall *) = { 0, @@ -106,6 +107,7 @@ (void *)&handleAwaitSyscall, (void *)&handleGetPhysicalSyscall, (void *)&handleForkSyscall, + (void *)&handleFreeSyscall, }; void processSyscall(Syscall *call) {