75 lines
2.6 KiB
ArmAsm
75 lines
2.6 KiB
ArmAsm
/* https://github.com/cirosantilli/x86-bare-metal-examples#bios-detect-memory */
|
|
|
|
#include "common.h"
|
|
BEGIN
|
|
CLEAR
|
|
STAGE2
|
|
mov $output, %di
|
|
call do_e820
|
|
|
|
/* Debug aid. */
|
|
PRINT_WORD_HEX <%bp>
|
|
PRINT_NEWLINE
|
|
|
|
mov %bp, %ax
|
|
mov $0, %dx
|
|
/* Each entry is 24 bytes wide. */
|
|
mov $24, %cx
|
|
mul %cx
|
|
PRINT_BYTES $output, <%ax>
|
|
hlt
|
|
|
|
/* This was copy pasted from:
|
|
* http://wiki.osdev.org/Detecting_Memory_%28x86%29#Getting_an_E820_Memory_Map
|
|
*
|
|
* use the INT 0x15, eax= 0xE820 BIOS function to get a memory map
|
|
* inputs: es:di -> destination buffer for 24 byte entries
|
|
* outputs: bp = entry count, trashes all registers except esi
|
|
*/
|
|
do_e820:
|
|
xorl %ebx,%ebx # ebx must be 0 to start
|
|
xorw %bp,%bp # keep an entry count in bp
|
|
movl $0x0534D4150,%edx # Place "SMAP" into edx
|
|
movl $0xe820,%eax
|
|
movl $1, %es:20(%di)
|
|
movl $24,%ecx # ask for 24 bytes
|
|
int $0x15
|
|
jc do_e820.failed # carry set on first call means "unsupported function"
|
|
movl $0x0534D4150,%edx # Some BIOSes apparently trash this register?
|
|
cmpl %edx,%eax # on success, eax must have been reset to "SMAP"
|
|
jne do_e820.failed
|
|
testl %ebx,%ebx # ebx = 0 implies list is only 1 entry long (worthless)
|
|
je do_e820.failed
|
|
jmp do_e820.jmpin
|
|
do_e820.e820lp:
|
|
movl $0xe820,%eax # eax, ecx get trashed on every int 0x15 call
|
|
movl $1, %es:20(%di)
|
|
movl $24,%ecx # ask for 24 bytes again
|
|
int $0x15
|
|
jc do_e820.e820f # carry set means "end of list already reached"
|
|
movl $0x0534D4150,%edx # repair potentially trashed register
|
|
do_e820.jmpin:
|
|
jcxz do_e820.skipent # skip any 0 length entries
|
|
cmpb $20,%cl # got a 24 byte ACPI 3.X response?
|
|
jbe do_e820.notext
|
|
testb $1, %es:29(%di)
|
|
je do_e820.skipent
|
|
do_e820.notext:
|
|
mov %ecx, %es:8(%di)
|
|
or %ecx, %es:12(%di)
|
|
jz do_e820.skipent # if length uint64_t is 0, skip entry
|
|
incw %bp # got a good entry: ++count, move to next storage spot
|
|
addw $24,%di
|
|
do_e820.skipent:
|
|
testl %ebx,%ebx # if ebx resets to 0, list is complete
|
|
jne do_e820.e820lp
|
|
do_e820.e820f:
|
|
#movw %bp,mmap_ent # store the entry count
|
|
clc # there is "jc" on end of list to this point, so the carry must be cleared
|
|
ret
|
|
do_e820.failed:
|
|
stc # "function unsupported" error exit
|
|
ret
|
|
|
|
output:
|