pluto/src/bootloader/memory.asm
Edward Dean 7678019e03 Feature/bootloader (#2), closes #1
* Added bootloader files

* Changed to spaces from tabs
2019-03-27 21:33:59 +00:00

117 lines
4.5 KiB
NASM

[bits 16]
; Get the number of KB of conventional memory up to 64KB.
; Output:
; AX - The number of KB of conventional memory or -1 if error.
%macro m_bios_get_conventional_memory_size 0
int 0x12
jc short .error_1
test ax, ax ; If size=0
je short .error_1
cmp ah, 0x86 ; Unsupported function
je short .error_1
cmp ah, 0x80 ; Invalid command
je short .error_1
ret
.error_1:
mov ax, -1
%endmacro
; Get the number of contiguous KB starting at 1MB of extended memory up to 64MB.
; Output:
; AX - The number of contiguous KB starting at 1MB of extended memory or -1 if error.
%macro bios_get_extended_memory_size 0
mov ax, 0x88
int 0x15
jc short .error_2
test ax, ax ; If size = 0
je short .error_2
cmp ah, 0x86 ; Unsupported function
je short .error_2
cmp ah, 0x80 ; Invalid command
je short .error_2
ret
.error_2:
mov ax, -1
%endmacro
; Get the memory size for above 64MB.
; Output:
; AX - KB between 1MB and 16MB. If error, then returns -1.
; BX - Number of 64KB blocks above 16MB
%macro m_bios_get_memory_size_E801 0
push ecx
push edx
xor ecx, ecx ; Clear all registers. This is needed for testing later
xor edx, edx
mov eax, 0x0000E801
int 0x15
jc short .error_3
cmp ah, 0x86 ; Unsupported function
je short .error_3
cmp ah, 0x80 ; Invalid command
je short .error_3
jcxz .use_ax ; BIOS may have stored it in AX, BX or CX, DX. Test if CX is 0
mov ax, cx ; It's not, so it should contain memory size; store it
mov bx, dx
.use_ax:
pop edx ; Memory size is in ax and bx already, return it
pop ecx
jmp short .end
.error_3:
mov ax, -1 ; Return -1 as there is an error
xor bx, bx ; Zero out BX
pop edx
pop ecx
.end:
%endmacro
; Get the memory map from the BIOS saying which areas of memory are reserved or available.
; Input:
; ES:DI - The memory segment where the memory map table will be saved to.
; Output:
; ESI - The number of memory map entries.
%macro m_bios_get_memory_map 0
xor ebx, ebx ; Start as 0, must preserve value after INT 0x15
xor esi, esi ; Number of entries
mov eax, 0x0000E820 ; INT 0x15 sub function 0xE820
mov ecx, 24 ; Memory map entry structure is 24 bytes
mov edx, 0x534D4150 ; SMAP
mov [es:di + 20], dword 0x00000001 ; Force a valid ACPI 3.x entry
int 0x15 ; Get first entry
jc short .error_4 ; If carry is set, then there was and error
cmp eax, 0x534D4150 ; BIOS returns SMAP in EAX
jne short .error_4
test ebx, ebx ; If EBX = 0 then list is one entry
je short .error_4 ; Then is worthless, so error.
jmp short .start
.next_entry:
mov eax, 0x0000E820
mov ecx, 24
mov edx, 0x534D4150
mov [es:di + 20], dword 0x00000001
int 0x15 ; Get next entry
jc short .done ; Carry set if end of list already reached
.start:
jcxz .skip_entry ; If actual returned bytes is 0, skip entry
cmp cl, 20 ; Has it returned a a 24 byte ACPI 3.x response
jbe short .notext
test byte [es:di + 20], 0x01 ; If so, is the 'ignore this data' bit set
jc short .skip_entry
.notext:
mov ecx, dword [es:di + 8] ; Save the lower 32 bit memory region lengths
or ecx, dword [es:di + 12] ; OR with upper region to test for zero
jz short .skip_entry ; If zero, the skip entry
inc esi ; Good entry so increment entry count and buffer offset
add di, 24
.skip_entry:
cmp ebx, 0 ; If EBX is 0, list is done
jne short .next_entry ; Get next entry if not zero
jmp short .done ; If zero then finish
.error_4:
m_reboot_with_msg memory_map_error
.done:
clc ; Clear the carry as was set before this point because of the JC.
%endmacro