diff options
Diffstat (limited to 'pc-bios/optionrom/multiboot.S')
-rw-r--r-- | pc-bios/optionrom/multiboot.S | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/pc-bios/optionrom/multiboot.S b/pc-bios/optionrom/multiboot.S index a0f3602956..b7efe4de34 100644 --- a/pc-bios/optionrom/multiboot.S +++ b/pc-bios/optionrom/multiboot.S @@ -123,6 +123,46 @@ mmap_store_entry: jnz mmap_loop mmap_done: + /* Calculate upper_mem field: The amount of memory between 1 MB and + the first upper memory hole. Get it from the mmap. */ + xor %di, %di + mov $0x100000, %edx +upper_mem_entry: + cmp %fs:0x2c, %di + je upper_mem_done + add $4, %di + + /* Skip if type != 1 */ + cmpl $1, %es:16(%di) + jne upper_mem_next + + /* Skip if > 4 GB */ + movl %es:4(%di), %eax + test %eax, %eax + jnz upper_mem_next + + /* Check for contiguous extension (base <= %edx < base + length) */ + movl %es:(%di), %eax + cmp %eax, %edx + jb upper_mem_next + addl %es:8(%di), %eax + cmp %eax, %edx + jae upper_mem_next + + /* If so, update %edx, and restart the search (mmap isn't ordered) */ + mov %eax, %edx + xor %di, %di + jmp upper_mem_entry + +upper_mem_next: + addl %es:-4(%di), %edi + jmp upper_mem_entry + +upper_mem_done: + sub $0x100000, %edx + shr $10, %edx + mov %edx, %fs:0x8 + real_to_prot: /* Load the GDT before going into protected mode */ lgdt: |