Files
x86-bare-metal-examples/bios_detect_memory.S
Ciro Santilli fb3c7e04c4 Move all documentation to README.adoc
This includes both separate .md files, and documentation that was on the
head of the .S source files.

Retest everything as this was done, and fix a few easy things.
2018-05-13 22:13:19 +01:00

74 lines
2.5 KiB
ArmAsm

#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: