/******************************************************************************

	COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.

	This file is part of Sortix.

	Sortix is free software: you can redistribute it and/or modify it under the
	terms of the GNU General Public License as published by the Free Software
	Foundation, either version 3 of the License, or (at your option) any later
	version.

	Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
	WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
	FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
	details.

	You should have received a copy of the GNU General Public License along
	with Sortix. If not, see <http://www.gnu.org/licenses/>.

	memorymanagement-asm.s
	Handles memory for the x86 architecture.

******************************************************************************/

.section .text

.globl _ZN6Sortix6Paging11FragmentizeEv
.type _ZN6Sortix6Paging11FragmentizeEv, @function # namespace Sortix { void Paging::Fragmentize(); }
_ZN6Sortix6Paging11FragmentizeEv:
	# Load the front of our linked list.
	mov 0x4(%esp), %ecx
	mov (%ecx), %eax # Load UnallocPage* Sortix::Paging::UnallocatedPage

FragLoop:
	testl %eax, %eax
	je FragDone

	movl 4(%eax), %edx
	movl 8(%eax), %ebx

	testl %ebx, %ebx
	je FragNext

	movl %eax, %ecx
	addl $0x1000, %ecx
	movl %ecx, 4(%eax)
	decl %ebx

FragFixupLoop:
	testl %ebx, %ebx
	je FragFixupLoopLastSwap

	movl $0xABBAACDC, 0(%ecx)
	addl $0x2000, %eax
	movl %eax, 4(%ecx)
	#movl $0, 8(%ecx)
	decl %ebx

	testl %ebx, %ebx
	je FragFixupLoopLast

	movl $0xABBAACDC, 0(%eax)
	addl $0x2000, %ecx
	movl %ecx, 4(%eax)
	#movl $0, 8(%eax)
	decl %ebx

	jmp FragFixupLoop

FragFixupLoopLastSwap:
	movl %ecx, %eax

FragFixupLoopLast:
	movl $0xABBAACDC, 0(%eax)
	movl %edx, 4(%eax)

FragNext:
	movl %edx, %eax
	jmp FragLoop

FragDone:
	ret	

.globl _ZN6Sortix6Paging8AllocateEv
.type _ZN6Sortix6Paging8AllocateEv, @function # namespace Sortix { void Paging::Allocate(); }
_ZN6Sortix6Paging8AllocateEv:
	# Load the front of our linked list.
	movl 0x4(%esp), %ecx
	movl (%ecx), %eax # Load UnallocPage* Sortix::Paging::UnallocatedPage

	# Test if we are out of memory.
	testl %eax, %eax
	je OutOfMem

	# TODO: Disable virtual memory here

	# Test if this page is unallocated, as a security measure.	
	movl (%eax), %ebx
	cmpl $0xABBAACDC, %ebx
	jne MagicFailure

	# Prepare the next front element in our linked list.
	movl 4(%eax), %edx
	jmp Done

MagicFailure:
	# The magic header in our page was invalid!
	movl %eax, %edx
	inc %eax # Set the lowest bit to signal a magic failure.

	# TODO: Panic the kernel here.

Done:
	# TODO: Enable virtual memory here

	# Update the front of our linked list to the next element.	
	movl %edx, (%ecx) # Save UnallocPage* Sortix::Paging::UnallocatedPage	
	ret

OutOfMem:
	# We run out of memory. Return NULL.
	movl $0, %eax
	ret

.globl _ZN6Sortix6Paging4FreeEPv
.type _ZN6Sortix6Paging4FreeEPv, @function # namespace Sortix { void Paging::Free(void* Page); }
_ZN6Sortix6Paging4FreeEPv:
	mov 0x4(%esp), %ecx
	mov (%ecx), %eax # Load UnallocPage* Sortix::Paging::UnallocatedPage
	mov 0x8(%esp), %edx

	# TODO: Disable virtual memory here

	movl $0xABBAACDC, (%edx)
	movl %eax, 4(%edx)
	#movl $0, 8(%edx)

	# TODO: Enable virtual memory here

	# Update the front of our linked list to the next element.	
	mov %edx, (%ecx) # Save UnallocPage* Sortix::Paging::UnallocatedPage	
	ret

