1 ; =============================================================================
2 ; BareMetal -- a 64-bit OS written in Assembly for x86-64 systems
3 ; Copyright (C) 2008-2011 Return Infinity -- see LICENSE.TXT
6 ; =============================================================================
13 ; -----------------------------------------------------------------------------
14 ; os_mem_allocate -- Allocates the requested number of 2 MiB pages
15 ; IN: RCX = Number of pages to allocate
16 ; OUT: RAX = Starting address
17 ; RCX = Number of pages allocated (Set to the value asked for or 0 on failure)
18 ; This function will only allocate continous pages
26 je os_mem_allocate_fail
; At least 1 page must be allocated
29 mov ax, word [os_MemAmount
]
30 shr ax, 1 ; Divide actual memory by 2
31 add rsi
, rax
; RSI now points to the last page
33 std ; Set direction flag to backward
35 os_mem_allocate_start: ; Find a free page of memory
37 cmp rsi
, os_MemoryMap
; We have hit the start of the memory map, no free pages
38 je os_mem_allocate_fail
39 cmp al, 1 ; If the byte is one then we found a free memory page
40 jne os_mem_allocate_start
41 mov rbx
, rcx
; RBX is our temporary counter
42 sub rbx
, 1 ; One free page was already found
43 cmp rbx
, 0 ; Was only one page requested?
44 je os_mem_allocate_mark
46 os_mem_allocate_nextpage:
48 cmp rsi
, os_MemoryMap
; We have hit the start of the memory map, no more free pages
49 je os_mem_allocate_fail
51 jne os_mem_allocate_start
54 jne os_mem_allocate_nextpage
57 ; We have a suitable free series of pages. Allocate them.
58 cld ; Set direction flag to forward
61 mov rdx
, rdi
; RDX points to the starting page
66 sub rdx
, os_MemoryMap
; RDX now contains the memory page number
67 shl rdx
, 21 ; Quick multiply by 2097152 (2 MiB) to get the starting memory address
68 mov rax
, rdx
; Return the starting address in RAX
69 jmp os_mem_allocate_end
72 cld ; Set direction flag to forward
73 xor rcx
, rcx
; Failure so set RCX to 0 (No pages allocated)
82 ; -----------------------------------------------------------------------------
85 ; -----------------------------------------------------------------------------
86 ; os_mem_release -- Frees the requested number of 2 MiB pages
87 ; IN: RAX = Starting address
88 ; RCX = Number of pages to free
89 ; OUT: RCX = Number of pages freed
95 shr rax
, 21 ; Quick divide by 2097152 (2 MiB) to get the starting page number
105 ; -----------------------------------------------------------------------------
108 ; -----------------------------------------------------------------------------
109 ; os_mem_get_free -- Returns the number of 2 MiB pages that are available
111 ; OUT: RCX = Number of free 2 MiB pages
117 mov rsi
, os_MemoryMap
121 os_mem_get_free_next:
125 je os_mem_get_free_end
127 jne os_mem_get_free_next
129 jmp os_mem_get_free_next
138 ; -----------------------------------------------------------------------------
141 ; =============================================================================