diff --git a/include/grub/i386/pc/init.h b/include/grub/i386/pc/init.h index 7dc8ee1f4..a6d2abf41 100644 --- a/include/grub/i386/pc/init.h +++ b/include/grub/i386/pc/init.h @@ -23,11 +23,6 @@ #include #include -/* Get a memory map entry. Return next continuation value. Zero means - the end. */ -grub_uint32_t grub_get_mmap_entry (struct grub_machine_mmap_entry *entry, - grub_uint32_t cont); - /* Turn on/off Gate A20. */ void grub_gate_a20 (int on); diff --git a/kern/i386/pc/mmap.c b/kern/i386/pc/mmap.c index 2758d17f8..25f8a739b 100644 --- a/kern/i386/pc/mmap.c +++ b/kern/i386/pc/mmap.c @@ -61,6 +61,53 @@ grub_get_eisa_mmap (void) return (regs.eax & 0xffff) | (regs.ebx << 16); } +/* + * + * grub_get_mmap_entry(addr, cont) : address and old continuation value (zero to + * start), for the Query System Address Map BIOS call. + * + * Sets the first 4-byte int value of "addr" to the size returned by + * the call. If the call fails, sets it to zero. + * + * Returns: new (non-zero) continuation value, 0 if done. + */ +/* Get a memory map entry. Return next continuation value. Zero means + the end. */ +static grub_uint32_t +grub_get_mmap_entry (struct grub_machine_mmap_entry *entry, + grub_uint32_t cont) +{ + struct grub_bios_int_registers regs; + + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + + /* place address (+4) in ES:DI */ + regs.es = ((grub_addr_t) &entry->addr) >> 4; + regs.edi = ((grub_addr_t) &entry->addr) & 0xf; + + /* set continuation value */ + regs.ebx = cont; + + /* set default maximum buffer size */ + regs.ecx = sizeof (*entry) - sizeof (entry->size); + + /* set EDX to 'SMAP' */ + regs.edx = 0x534d4150; + + regs.eax = 0xe820; + grub_bios_interrupt (0x15, ®s); + + /* write length of buffer (zero if error) into ADDR */ + if ((regs.flags & GRUB_CPU_INT_FLAGS_CARRY) || regs.eax != 0x534d4150 + || regs.ecx < 0x14 || regs.ecx > 0x400) + entry->size = 0; + else + entry->size = regs.ecx; + + /* return the continuation value */ + return regs.ebx; +} + grub_err_t grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)) { diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S index 3fa1b11e8..ee677fc15 100644 --- a/kern/i386/pc/startup.S +++ b/kern/i386/pc/startup.S @@ -505,94 +505,6 @@ FUNCTION(grub_chainloader_real_boot) #include "../loader.S" -/* - * - * grub_get_mmap_entry(addr, cont) : address and old continuation value (zero to - * start), for the Query System Address Map BIOS call. - * - * Sets the first 4-byte int value of "addr" to the size returned by - * the call. If the call fails, sets it to zero. - * - * Returns: new (non-zero) continuation value, 0 if done. - */ - -FUNCTION(grub_get_mmap_entry) - pushl %ebp - pushl %ebx - pushl %edi - pushl %esi - - /* push ADDR */ - pushl %eax - - /* place address (+4) in ES:DI */ - addl $4, %eax - movl %eax, %edi - andl $0xf, %edi - shrl $4, %eax - movl %eax, %esi - - /* set continuation value */ - movl %edx, %ebx - - /* set default maximum buffer size */ - movl $0x14, %ecx - - /* set EDX to 'SMAP' */ - movl $0x534d4150, %edx - - call prot_to_real /* enter real mode */ - .code16 - - movw %si, %es - movl $0xe820, %eax - int $0x15 - - DATA32 jc xnosmap - - cmpl $0x534d4150, %eax - jne xnosmap - - cmpl $0x14, %ecx - jl xnosmap - - cmpl $0x400, %ecx - jg xnosmap - - jmp xsmap - -xnosmap: - xorl %ecx, %ecx - -/* Apple's cc jumps few bytes before the correct - label in this context. Hence nops. */ -#ifdef APPLE_CC - nop - nop - nop - nop - nop - nop -#endif - -xsmap: - DATA32 call real_to_prot - .code32 - - /* write length of buffer (zero if error) into ADDR */ - popl %eax - movl %ecx, (%eax) - - /* set return value to continuation */ - movl %ebx, %eax - - popl %esi - popl %edi - popl %ebx - popl %ebp - ret - - /* * void grub_console_real_putchar (int c) *