merge mainline into intwrap

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-08-29 23:21:21 +02:00
commit 069c9c5fda
137 changed files with 8057 additions and 3591 deletions

View file

@ -682,20 +682,3 @@ grub_dl_unload_unneeded (void)
p = p->next;
}
}
/* Unload all modules. */
void
grub_dl_unload_all (void)
{
while (grub_dl_head)
{
grub_dl_t p;
grub_dl_unload_unneeded ();
/* Force to decrement the ref count. This will purge pre-loaded
modules and manually inserted modules. */
for (p = grub_dl_head; p; p = p->next)
p->ref_count--;
}
}

View file

@ -174,17 +174,6 @@ grub_reboot (void)
}
#endif
int
grub_efi_exit_boot_services (grub_efi_uintn_t map_key)
{
grub_efi_boot_services_t *b;
grub_efi_status_t status;
b = grub_efi_system_table->boot_services;
status = efi_call_2 (b->exit_boot_services, grub_efi_image_handle, map_key);
return status == GRUB_EFI_SUCCESS;
}
grub_err_t
grub_efi_set_virtual_address_map (grub_efi_uintn_t memory_map_size,
grub_efi_uintn_t descriptor_size,
@ -751,26 +740,3 @@ grub_efi_print_device_path (grub_efi_device_path_t *dp)
dp = (grub_efi_device_path_t *) ((char *) dp + len);
}
}
int
grub_efi_finish_boot_services (void)
{
grub_efi_uintn_t mmap_size = 0;
grub_efi_uintn_t map_key;
grub_efi_uintn_t desc_size;
grub_efi_uint32_t desc_version;
void *mmap_buf = 0;
if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key,
&desc_size, &desc_version) < 0)
return 0;
mmap_buf = grub_malloc (mmap_size);
if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key,
&desc_size, &desc_version) <= 0)
return 0;
return grub_efi_exit_boot_services (map_key);
}

View file

@ -49,6 +49,12 @@ static struct allocated_page *allocated_pages = 0;
#define MIN_HEAP_SIZE 0x100000
#define MAX_HEAP_SIZE (1600 * 0x100000)
static void *finish_mmap_buf = 0;
static grub_efi_uintn_t finish_mmap_size = 0;
static grub_efi_uintn_t finish_key = 0;
static grub_efi_uintn_t finish_desc_size;
static grub_efi_uint32_t finish_desc_version;
int grub_efi_is_finished = 0;
/* Allocate pages. Return the pointer to the first of allocated pages. */
void *
@ -140,6 +146,51 @@ grub_efi_free_pages (grub_efi_physical_address_t address,
efi_call_2 (b->free_pages, address, pages);
}
grub_err_t
grub_efi_finish_boot_services (grub_efi_uintn_t *outbuf_size, void *outbuf,
grub_efi_uintn_t *map_key,
grub_efi_uintn_t *efi_desc_size,
grub_efi_uint32_t *efi_desc_version)
{
grub_efi_boot_services_t *b;
grub_efi_status_t status;
if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf, &finish_key,
&finish_desc_size, &finish_desc_version) < 0)
return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
if (outbuf && *outbuf_size < finish_mmap_size)
return grub_error (GRUB_ERR_IO, "memory map buffer is too small");
finish_mmap_buf = grub_malloc (finish_mmap_size);
if (!finish_mmap_buf)
return grub_errno;
if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf, &finish_key,
&finish_desc_size, &finish_desc_version) <= 0)
return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
b = grub_efi_system_table->boot_services;
status = efi_call_2 (b->exit_boot_services, grub_efi_image_handle,
finish_key);
if (status != GRUB_EFI_SUCCESS)
return grub_error (GRUB_ERR_IO, "couldn't terminate EFI services");
grub_efi_is_finished = 1;
if (outbuf_size)
*outbuf_size = finish_mmap_size;
if (outbuf)
grub_memcpy (outbuf, finish_mmap_buf, finish_mmap_size);
if (map_key)
*map_key = finish_key;
if (efi_desc_size)
*efi_desc_size = finish_desc_size;
if (efi_desc_version)
*efi_desc_version = finish_desc_version;
return GRUB_ERR_NONE;
}
/* Get the memory map as defined in the EFI spec. Return 1 if successful,
return 0 if partial, or return -1 if an error occurs. */
int
@ -154,6 +205,29 @@ grub_efi_get_memory_map (grub_efi_uintn_t *memory_map_size,
grub_efi_uintn_t key;
grub_efi_uint32_t version;
if (grub_efi_is_finished)
{
int ret = 1;
if (*memory_map_size < finish_mmap_size)
{
grub_memcpy (memory_map, finish_mmap_buf, *memory_map_size);
ret = 0;
}
else
{
grub_memcpy (memory_map, finish_mmap_buf, finish_mmap_size);
ret = 1;
}
*memory_map_size = finish_mmap_size;
if (map_key)
*map_key = finish_key;
if (descriptor_size)
*descriptor_size = finish_desc_size;
if (descriptor_version)
*descriptor_version = finish_desc_version;
return ret;
}
/* Allow some parameters to be missing. */
if (! map_key)
map_key = &key;

View file

@ -140,7 +140,7 @@ grub_elf32_load_phdrs (grub_elf_t elf)
return GRUB_ERR_NONE;
}
static grub_err_t
grub_err_t
grub_elf32_phdr_iterate (grub_elf_t elf,
int NESTED_FUNC_ATTR (*hook) (grub_elf_t, Elf32_Phdr *, void *),
void *hook_arg)
@ -326,7 +326,7 @@ grub_elf64_load_phdrs (grub_elf_t elf)
return GRUB_ERR_NONE;
}
static grub_err_t
grub_err_t
grub_elf64_phdr_iterate (grub_elf_t elf,
int NESTED_FUNC_ATTR (*hook) (grub_elf_t, Elf64_Phdr *, void *),
void *hook_arg)

View file

@ -40,9 +40,6 @@
extern char _start[];
extern char _end[];
grub_addr_t grub_os_area_addr;
grub_size_t grub_os_area_size;
grub_uint32_t
grub_get_rtc (void)
{
@ -93,20 +90,7 @@ grub_machine_init (void)
}
}
if (addr == GRUB_MEMORY_MACHINE_UPPER_START
|| (addr >= GRUB_MEMORY_MACHINE_LOWER_SIZE
&& addr <= GRUB_MEMORY_MACHINE_UPPER_START
&& (addr + size > GRUB_MEMORY_MACHINE_UPPER_START)))
{
grub_size_t quarter = size >> 2;
grub_os_area_addr = addr;
grub_os_area_size = size - quarter;
grub_mm_init_region ((void *) (grub_os_area_addr + grub_os_area_size),
quarter);
}
else
grub_mm_init_region ((void *) (grub_addr_t) addr, (grub_size_t) size);
grub_mm_init_region ((void *) (grub_addr_t) addr, (grub_size_t) size);
return 0;
}

View file

@ -85,7 +85,3 @@ codestart:
*/
#include "../realmode.S"
/*
* Routines needed by Linux and Multiboot loaders.
*/
#include "../loader.S"

View file

@ -63,7 +63,3 @@ codestart:
*/
#include "../realmode.S"
/*
* Routines needed by Linux and Multiboot loaders.
*/
#include "../loader.S"

View file

@ -1,124 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Note: These functions defined in this file may be called from C.
* Be careful of that you must not modify some registers. Quote
* from gcc-2.95.2/gcc/config/i386/i386.h:
1 for registers not available across function calls.
These must include the FIXED_REGISTERS and also any
registers that can be used without being saved.
The latter must include the registers where values are returned
and the register where structure-value addresses are passed.
Aside from that, you can include as many other registers as you like.
ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg
{ 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
*/
/*
* Note: GRUB is compiled with the options -mrtd and -mregparm=3.
* So the first three arguments are passed in %eax, %edx, and %ecx,
* respectively, and if a function has a fixed number of arguments
* and the number if greater than three, the function must return
* with "ret $N" where N is ((the number of arguments) - 3) * 4.
*/
/*
* This is the area for all of the special variables.
*/
#include <grub/i386/floppy.h>
.p2align 2 /* force 4-byte alignment */
/*
* void grub_linux_boot_zimage (void)
*/
VARIABLE(grub_linux_prot_size)
.long 0
VARIABLE(grub_linux_tmp_addr)
.long 0
VARIABLE(grub_linux_real_addr)
.long 0
VARIABLE(grub_linux_is_bzimage)
.long 0
FUNCTION(grub_linux16_real_boot)
/* Must be done before zImage copy. */
call EXT_C(grub_dl_unload_all)
movl EXT_C(grub_linux_is_bzimage), %ebx
test %ebx, %ebx
jne bzimage
/* copy the kernel */
movl EXT_C(grub_linux_prot_size), %ecx
addl $3, %ecx
shrl $2, %ecx
movl $GRUB_LINUX_BZIMAGE_ADDR, %esi
movl $GRUB_LINUX_ZIMAGE_ADDR, %edi
cld
rep
movsl
bzimage:
movl EXT_C(grub_linux_real_addr), %ebx
/* copy the real mode code */
movl EXT_C(grub_linux_tmp_addr), %esi
movl %ebx, %edi
movl $GRUB_LINUX_SETUP_MOVE_SIZE, %ecx
cld
rep
movsb
/* change %ebx to the segment address */
shrl $4, %ebx
movl %ebx, %eax
addl $0x20, %eax
movw %ax, linux_setup_seg
/* XXX new stack pointer in safe area for calling functions */
movl $0x4000, %esp
movw $GRUB_FLOPPY_REG_DIGITAL_OUTPUT, %dx
xorb %al, %al
outb %al, %dx
/* final setup for linux boot */
call prot_to_real
.code16
cli
movw %bx, %ss
movw $GRUB_LINUX_SETUP_STACK, %sp
movw %bx, %ds
movw %bx, %es
movw %bx, %fs
movw %bx, %gs
/* ljmp */
.byte 0xea
.word 0
linux_setup_seg:
.word 0
.code32

View file

@ -45,9 +45,6 @@ struct mem_region
static struct mem_region mem_regions[MAX_REGIONS];
static int num_regions;
grub_addr_t grub_os_area_addr;
grub_size_t grub_os_area_size;
static char *
make_install_device (void)
{
@ -220,25 +217,9 @@ grub_machine_init (void)
compact_mem_regions ();
/* Add the memory regions to free memory, except for the region starting
from 1MB. This region is partially used for loading OS images.
For now, 1/4 of this is added to free memory. */
for (i = 0; i < num_regions; i++)
if (mem_regions[i].addr == 0x100000)
{
grub_size_t quarter = mem_regions[i].size >> 2;
grub_os_area_addr = mem_regions[i].addr;
grub_os_area_size = mem_regions[i].size - quarter;
grub_mm_init_region ((void *) (grub_os_area_addr + grub_os_area_size),
quarter);
}
else
grub_mm_init_region ((void *) mem_regions[i].addr, mem_regions[i].size);
if (! grub_os_area_addr)
grub_fatal ("no upper memory");
grub_tsc_init ();
}

View file

@ -474,8 +474,6 @@ FUNCTION(grub_chainloader_real_boot)
pushl %edx
pushl %eax
call EXT_C(grub_dl_unload_all)
/* Turn off Gate A20 */
xorl %eax, %eax
call EXT_C(grub_gate_a20)
@ -491,8 +489,6 @@ FUNCTION(grub_chainloader_real_boot)
ljmp $0, $GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR
.code32
#include "../loader.S"
/*
* void grub_console_putchar (int c)
*

View file

@ -67,6 +67,11 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uin
GRUB_MACHINE_MEMORY_AVAILABLE))
return 1;
if (hook ((grub_addr_t) _end,
0xa0000 - (grub_addr_t) _end,
GRUB_MACHINE_MEMORY_AVAILABLE))
return 1;
if (hook (GRUB_MEMORY_MACHINE_UPPER,
0x100000 - GRUB_MEMORY_MACHINE_UPPER,
GRUB_MACHINE_MEMORY_RESERVED))

View file

@ -184,6 +184,7 @@ grub_real_dprintf (const char *file, const int line, const char *condition,
va_start (args, fmt);
grub_vprintf (fmt, args);
va_end (args);
grub_refresh ();
}
}

View file

@ -65,6 +65,7 @@
#include <grub/types.h>
#include <grub/disk.h>
#include <grub/dl.h>
#include <grub/mm_private.h>
#ifdef MM_DEBUG
# undef grub_malloc
@ -74,45 +75,9 @@
# undef grub_memalign
#endif
/* Magic words. */
#define GRUB_MM_FREE_MAGIC 0x2d3c2808
#define GRUB_MM_ALLOC_MAGIC 0x6db08fa4
typedef struct grub_mm_header
{
struct grub_mm_header *next;
grub_size_t size;
grub_size_t magic;
#if GRUB_CPU_SIZEOF_VOID_P == 4
char padding[4];
#elif GRUB_CPU_SIZEOF_VOID_P == 8
char padding[8];
#else
# error "unknown word size"
#endif
}
*grub_mm_header_t;
#if GRUB_CPU_SIZEOF_VOID_P == 4
# define GRUB_MM_ALIGN_LOG2 4
#elif GRUB_CPU_SIZEOF_VOID_P == 8
# define GRUB_MM_ALIGN_LOG2 5
#endif
#define GRUB_MM_ALIGN (1 << GRUB_MM_ALIGN_LOG2)
typedef struct grub_mm_region
{
struct grub_mm_header *first;
struct grub_mm_region *next;
grub_addr_t addr;
grub_size_t size;
}
*grub_mm_region_t;
static grub_mm_region_t base;
grub_mm_region_t grub_mm_base;
/* Get a header from the pointer PTR, and set *P and *R to a pointer
to the header and a pointer to its region, respectively. PTR must
@ -123,9 +88,9 @@ get_header_from_pointer (void *ptr, grub_mm_header_t *p, grub_mm_region_t *r)
if ((grub_addr_t) ptr & (GRUB_MM_ALIGN - 1))
grub_fatal ("unaligned pointer %p", ptr);
for (*r = base; *r; *r = (*r)->next)
if ((grub_addr_t) ptr > (*r)->addr
&& (grub_addr_t) ptr <= (*r)->addr + (*r)->size)
for (*r = grub_mm_base; *r; *r = (*r)->next)
if ((grub_addr_t) ptr > (grub_addr_t) ((*r) + 1)
&& (grub_addr_t) ptr <= (grub_addr_t) ((*r) + 1) + (*r)->size)
break;
if (! *r)
@ -156,18 +121,18 @@ grub_mm_init_region (void *addr, grub_size_t size)
if (size < GRUB_MM_ALIGN)
return;
h = (grub_mm_header_t) ((char *) r + GRUB_MM_ALIGN);
h = (grub_mm_header_t) (r + 1);
h->next = h;
h->magic = GRUB_MM_FREE_MAGIC;
h->size = (size >> GRUB_MM_ALIGN_LOG2);
r->first = h;
r->addr = (grub_addr_t) h;
r->pre_size = (grub_addr_t) r - (grub_addr_t) addr;
r->size = (h->size << GRUB_MM_ALIGN_LOG2);
/* Find where to insert this region. Put a smaller one before bigger ones,
to prevent fragmentation. */
for (p = &base, q = *p; q; p = &(q->next), q = *p)
for (p = &grub_mm_base, q = *p; q; p = &(q->next), q = *p)
if (q->size > r->size)
break;
@ -206,6 +171,7 @@ grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align)
if (p->size >= n + extra)
{
extra += (p->size - extra - n) & (~(align - 1));
if (extra == 0 && p->size == n)
{
/* There is no special alignment requirement and memory block
@ -284,10 +250,10 @@ grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align)
r = p + extra + n;
r->magic = GRUB_MM_FREE_MAGIC;
r->size = p->size - extra - n;
r->next = p->next;
r->next = p;
p->size = extra;
p->next = r;
q->next = r;
p += extra;
}
@ -318,13 +284,16 @@ grub_memalign (grub_size_t align, grub_size_t size)
grub_size_t n = ((size + GRUB_MM_ALIGN - 1) >> GRUB_MM_ALIGN_LOG2) + 1;
int count = 0;
if (!grub_mm_base)
goto fail;
align = (align >> GRUB_MM_ALIGN_LOG2);
if (align == 0)
align = 1;
again:
for (r = base; r; r = r->next)
for (r = grub_mm_base; r; r = r->next)
{
void *p;
@ -352,6 +321,7 @@ grub_memalign (grub_size_t align, grub_size_t size)
break;
}
fail:
grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
return 0;
}
@ -485,7 +455,7 @@ grub_mm_dump_free (void)
{
grub_mm_region_t r;
for (r = base; r; r = r->next)
for (r = grub_mm_base; r; r = r->next)
{
grub_mm_header_t p;
@ -512,13 +482,13 @@ grub_mm_dump (unsigned lineno)
grub_mm_region_t r;
grub_printf ("called at line %u\n", lineno);
for (r = base; r; r = r->next)
for (r = grub_mm_base; r; r = r->next)
{
grub_mm_header_t p;
for (p = (grub_mm_header_t) ((r->addr + GRUB_MM_ALIGN - 1)
& (~(GRUB_MM_ALIGN - 1)));
(grub_addr_t) p < r->addr + r->size;
for (p = (grub_mm_header_t) ALIGN_UP ((grub_addr_t) (r + 1),
GRUB_MM_ALIGN);
(grub_addr_t) p < (grub_addr_t) (r+1) + r->size;
p++)
{
switch (p->magic)

View file

@ -1,7 +1,7 @@
/* cache.S - Flush the processor cache for a specific region. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2004,2007 Free Software Foundation, Inc.
* Copyright (C) 2004,2007,2010 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -17,32 +17,10 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#define CACHE_LINE_BYTES 32
.text
.align 2
.globl grub_arch_sync_caches
grub_arch_sync_caches:
/* `address' may not be CACHE_LINE_BYTES-aligned. */
andi. 6, 3, CACHE_LINE_BYTES - 1 /* Find the misalignment. */
add 4, 4, 6 /* Adjust `size' to compensate. */
/* Force the dcache lines to memory. */
li 5, 0
1: dcbst 5, 3
addi 5, 5, CACHE_LINE_BYTES
cmpw 5, 4
blt 1b
sync /* Force all dcbsts to complete. */
/* Invalidate the icache lines. */
li 5, 0
1: icbi 5, 3
addi 5, 5, CACHE_LINE_BYTES
cmpw 5, 4
blt 1b
sync /* Force all icbis to complete. */
isync /* Discard partially executed instructions that were
loaded from the invalid icache. */
#include "cache_flush.S"
blr

View file

@ -0,0 +1,43 @@
/* cache.S - Flush the processor cache for a specific region. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2004,2007,2010 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#undef CACHE_LINE_BYTES
#define CACHE_LINE_BYTES 32
/* `address' may not be CACHE_LINE_BYTES-aligned. */
andi. 6, 3, CACHE_LINE_BYTES - 1 /* Find the misalignment. */
add 4, 4, 6 /* Adjust `size' to compensate. */
/* Force the dcache lines to memory. */
li 5, 0
1: dcbst 5, 3
addi 5, 5, CACHE_LINE_BYTES
cmpw 5, 4
blt 1b
sync /* Force all dcbsts to complete. */
/* Invalidate the icache lines. */
li 5, 0
1: icbi 5, 3
addi 5, 5, CACHE_LINE_BYTES
cmpw 5, 4
blt 1b
sync /* Force all icbis to complete. */
isync /* Discard partially executed instructions that were
loaded from the invalid icache. */