1 .code16 2 3#define SMAP 0x534d4150 4#define E820_BIOS_MAX 128 5 6get_memory_map: 7 8.Lmeme820: 9 xorl %ebx, %ebx # continuation counter 10 movw $bootsym(e820map), %di # point into the whitelist 11 # so we can have the bios 12 # directly write into it. 13 141: movl $0x0000e820, %eax # e820, upper word zeroed 15 movl $SMAP,%edx # ascii 'SMAP' 16 movl $20,%ecx # size of the e820rec 17 pushw %ds # data record. 18 popw %es 19 int $0x15 20 jc .Lmem88 21 22 cmpl $SMAP,%eax # check the return is `SMAP' 23 jne .Lmem88 24 25 movb bootsym(e820nr),%al # up to 128 entries 26 cmpb $E820_BIOS_MAX,%al 27 jae .Lmem88 28 29 incb bootsym(e820nr) 30 movw %di,%ax 31 addw $20,%ax 32 movw %ax,%di 33 cmpl $0,%ebx # check to see if 34 jne 1b # %ebx is set to EOF 35 36.Lmem88: 37 movb $0x88, %ah 38 int $0x15 39 movw %ax,bootsym(highmem_kb) 40 41.Lmeme801: 42 stc # fix to work around buggy 43 xorw %cx,%cx # BIOSes which don't clear/set 44 xorw %dx,%dx # carry on pass/error of 45 # e801h memory size call 46 # or merely pass cx,dx though 47 # without changing them. 48 movw $0xe801, %ax 49 int $0x15 50 jc .Lint12 51 52 cmpw $0x0, %cx # Kludge to handle BIOSes 53 jne 1f # which report their extended 54 cmpw $0x0, %dx # memory in AX/BX rather than 55 jne 1f # CX/DX. The spec I have read 56 movw %ax, %cx # seems to indicate AX/BX 57 movw %bx, %dx # are more reasonable anyway... 581: andl $0xffff,%edx # clear sign extend 59 shll $6,%edx # and go from 64k to 1k chunks 60 movl %edx,bootsym(highmem_kb) # store extended memory size 61 andl $0xffff,%ecx # clear sign extend 62 addl %ecx,bootsym(highmem_kb) # and add lower memory into 63 64.Lint12: 65 int $0x12 66 movw %ax,bootsym(lowmem_kb) 67 68 ret 69 70/* 71 * Copy E820 map obtained from BIOS to a buffer allocated by Xen. 72 * Input: %rdi: target address of e820 entry array 73 * %esi: maximum number of entries to copy 74 * Output: %eax: number of entries copied 75 */ 76 .code64 77ENTRY(e820map_copy) 78 mov %esi, %eax 79 lea e820map(%rip), %rsi 80 mov e820nr(%rip), %ecx 81 cmp %ecx, %eax 82 cmova %ecx, %eax # number of entries to move 83 imul $5, %eax, %ecx 84 rep movsl # do the move 85 ret 86 87 .align 4 88e820map: 89 .fill E820_BIOS_MAX*20,1,0 90e820nr: 91 .long 0 92GLOBAL(lowmem_kb) 93 .long 0 94GLOBAL(highmem_kb) 95 .long 0 96