merge mainline into arm

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2013-05-11 10:24:24 +02:00
commit 8e71d87482
490 changed files with 29659 additions and 8612 deletions

View file

@ -51,6 +51,7 @@ grub_dl_t grub_dl_head = 0;
grub_err_t
grub_dl_add (grub_dl_t mod);
/* Keep global so that GDB scripts work. */
grub_err_t
grub_dl_add (grub_dl_t mod)
{
@ -58,9 +59,6 @@ grub_dl_add (grub_dl_t mod)
return grub_error (GRUB_ERR_BAD_MODULE,
"`%s' is already loaded", mod->name);
mod->next = grub_dl_head;
grub_dl_head = mod;
return GRUB_ERR_NONE;
}
@ -77,18 +75,6 @@ grub_dl_remove (grub_dl_t mod)
}
}
grub_dl_t
grub_dl_get (const char *name)
{
grub_dl_t l;
for (l = grub_dl_head; l; l = l->next)
if (grub_strcmp (name, l->name) == 0)
return l;
return 0;
}
struct grub_symbol
@ -359,6 +345,8 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e)
#ifdef GRUB_MODULES_MACHINE_READONLY
mod->symtab = grub_malloc (s->sh_size);
if (!mod->symtab)
return grub_errno;
memcpy (mod->symtab, (char *) e + s->sh_offset, s->sh_size);
#else
mod->symtab = (Elf_Sym *) ((char *) e + s->sh_offset);
@ -445,13 +433,6 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e)
return GRUB_ERR_NONE;
}
static void
grub_dl_call_init (grub_dl_t mod)
{
if (mod->init)
(mod->init) (mod);
}
/* Me, Vladimir Serbinenko, hereby I add this module check as per new
GNU module policy. Note that this license check is informative only.
Modules have to be licensed under GPLv3 or GPLv3+ (optionally
@ -593,7 +574,7 @@ grub_dl_flush_cache (grub_dl_t mod)
/* Load a module from core memory. */
grub_dl_t
grub_dl_load_core (void *addr, grub_size_t size)
grub_dl_load_core_noinit (void *addr, grub_size_t size)
{
Elf_Ehdr *e;
grub_dl_t mod;
@ -649,10 +630,6 @@ grub_dl_load_core (void *addr, grub_size_t size)
grub_dprintf ("modules", "module name: %s\n", mod->name);
grub_dprintf ("modules", "init function: %p\n", mod->init);
grub_boot_time ("Initing module %s", mod->name);
grub_dl_call_init (mod);
grub_boot_time ("Module %s inited", mod->name);
if (grub_dl_add (mod))
{
grub_dl_unload (mod);
@ -662,6 +639,23 @@ grub_dl_load_core (void *addr, grub_size_t size)
return mod;
}
grub_dl_t
grub_dl_load_core (void *addr, grub_size_t size)
{
grub_dl_t mod;
mod = grub_dl_load_core_noinit (addr, size);
if (!mod)
return NULL;
grub_boot_time ("Initing module %s", mod->name);
grub_dl_init (mod);
grub_boot_time ("Module %s inited", mod->name);
return mod;
}
/* Load a module from the file FILENAME. */
grub_dl_t
grub_dl_load_file (const char *filename)
@ -716,6 +710,9 @@ grub_dl_load (const char *name)
if (mod)
return mod;
if (grub_no_modules)
return 0;
if (! grub_dl_dir) {
grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix");
return 0;

View file

@ -101,8 +101,20 @@ grub_elfXX_load (grub_elf_t elf, const char *filename,
continue;
load_addr = (grub_addr_t) phdr->p_paddr;
if (load_flags & GRUB_ELF_LOAD_FLAGS_28BITS)
load_addr &= 0xFFFFFFF;
switch (load_flags & GRUB_ELF_LOAD_FLAGS_BITS)
{
case GRUB_ELF_LOAD_FLAGS_ALL_BITS:
break;
case GRUB_ELF_LOAD_FLAGS_28BITS:
load_addr &= 0xFFFFFFF;
break;
case GRUB_ELF_LOAD_FLAGS_30BITS:
load_addr &= 0x3FFFFFFF;
break;
case GRUB_ELF_LOAD_FLAGS_62BITS:
load_addr &= 0x3FFFFFFFFFFFFFFFULL;
break;
}
load_addr += (grub_addr_t) load_offset;
if (load_addr < load_base)

View file

@ -18,6 +18,7 @@
*/
#include <config.h>
#include <config-util.h>
#define _GNU_SOURCE 1
#include <stdlib.h>

View file

@ -0,0 +1,2 @@
#include <config-util.h>
#include "../../gnulib/error.c"

View file

@ -24,6 +24,8 @@
#include <grub/emu/misc.h>
#include <grub/disk.h>
const int grub_no_modules = 1;
void
grub_register_exported_symbols (void)
{
@ -44,12 +46,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
return GRUB_ERR_BAD_MODULE;
}
void
grub_emu_init (void)
{
grub_no_autoload = 1;
}
#if defined (__ia64__) || defined (__powerpc__)
void grub_arch_dl_get_tramp_got_size (const void *ehdr __attribute__ ((unused)),
grub_size_t *tramp, grub_size_t *got)
@ -66,7 +62,3 @@ grub_arch_dl_init_linker (void)
}
#endif
void
grub_emu_post_init (void)
{
}

View file

@ -17,6 +17,8 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config-util.h>
#include <grub/disk.h>
#include <grub/partition.h>
#include <grub/msdos_partition.h>
@ -431,7 +433,7 @@ grub_util_get_dm_node_linear_info (const char *dev,
uint64_t length, start;
char *target, *params;
char *ptr;
int major, minor;
int major = 0, minor = 0;
int first = 1;
grub_disk_addr_t partstart = 0;
@ -497,6 +499,8 @@ grub_util_get_dm_node_linear_info (const char *dev,
dm_task_destroy (dmt);
first = 0;
if (!dm_is_dm_major (major))
break;
}
if (first)
return 0;

View file

@ -16,6 +16,9 @@
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config-util.h>
#define _BSD_SOURCE
#include <grub/fs.h>
#include <grub/file.h>

View file

@ -21,6 +21,8 @@
#error "No target cpu type is defined"
#endif
const int grub_no_modules = 0;
/* grub-emu-lite supports dynamic module loading, so it won't have any
embedded modules. */
void
@ -34,14 +36,3 @@ grub_fini_all (void)
{
return;
}
void
grub_emu_init (void)
{
return;
}
void
grub_emu_post_init (void)
{
}

View file

@ -16,6 +16,9 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <config-util.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
@ -52,8 +55,6 @@ static jmp_buf main_env;
/* Store the prefix specified by an argument. */
static char *root_dev = NULL, *dir = NULL;
int grub_no_autoload;
grub_addr_t grub_modbase = 0;
void
@ -168,7 +169,6 @@ void grub_hostfs_init (void);
void grub_hostfs_fini (void);
void grub_host_init (void);
void grub_host_fini (void);
void grub_emu_init (void);
int
main (int argc, char *argv[])
@ -205,7 +205,6 @@ main (int argc, char *argv[])
}
signal (SIGINT, SIG_IGN);
grub_emu_init ();
grub_console_init ();
grub_host_init ();
@ -216,8 +215,6 @@ main (int argc, char *argv[])
grub_hostfs_init ();
grub_emu_post_init ();
/* Make sure that there is a root device. */
if (! root_dev)
root_dev = grub_strdup ("host");

View file

@ -145,36 +145,6 @@ xstrdup (const char *str)
return newstr;
}
#ifndef HAVE_VASPRINTF
int
vasprintf (char **buf, const char *fmt, va_list ap)
{
/* Should be large enough. */
*buf = xmalloc (512);
return vsnprintf (*buf, 512, fmt, ap);
}
#endif
#ifndef HAVE_ASPRINTF
int
asprintf (char **buf, const char *fmt, ...)
{
int status;
va_list ap;
va_start (ap, fmt);
status = vasprintf (buf, fmt, ap);
va_end (ap);
return status;
}
#endif
char *
xasprintf (const char *fmt, ...)
{
@ -182,12 +152,9 @@ xasprintf (const char *fmt, ...)
char *result;
va_start (ap, fmt);
if (vasprintf (&result, fmt, ap) < 0)
{
if (errno == ENOMEM)
grub_util_error ("%s", _("out of memory"));
return NULL;
}
result = grub_xvasprintf (fmt, ap);
if (!result)
grub_util_error ("%s", _("out of memory"));
return result;
}

View file

@ -64,7 +64,7 @@ grub_file_open (const char *name)
grub_device_t device = 0;
grub_file_t file = 0, last_file = 0;
char *device_name;
char *file_name;
const char *file_name;
grub_file_filter_id_t filter;
device_name = grub_file_get_device_name (name);
@ -76,7 +76,7 @@ grub_file_open (const char *name)
if (file_name)
file_name++;
else
file_name = (char *) name;
file_name = name;
device = grub_device_open (device_name);
grub_free (device_name);

View file

@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
* Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2013 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
@ -34,9 +34,6 @@
#include <grub/cpu/io.h>
#include <grub/cpu/floppy.h>
#include <grub/cpu/tsc.h>
#ifdef GRUB_MACHINE_QEMU
#include <grub/machine/kernel.h>
#endif
extern grub_uint8_t _start[];
extern grub_uint8_t _end[];
@ -51,12 +48,8 @@ grub_exit (void)
grub_cpu_idle ();
}
#ifdef GRUB_MACHINE_QEMU
grub_addr_t grub_modbase;
#else
grub_addr_t grub_modbase = GRUB_KERNEL_I386_COREBOOT_MODULES_ADDR;
static grub_uint64_t modend;
#endif
/* Helper for grub_machine_init. */
static int
@ -80,10 +73,8 @@ heap_init (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type,
if (begin < GRUB_MEMORY_MACHINE_LOWER_SIZE)
begin = GRUB_MEMORY_MACHINE_LOWER_SIZE;
#ifndef GRUB_MACHINE_QEMU
if (modend && begin < modend)
begin = modend;
#endif
if (end <= begin)
return 0;
@ -96,18 +87,11 @@ heap_init (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type,
void
grub_machine_init (void)
{
#ifdef GRUB_MACHINE_QEMU
grub_modbase = grub_core_entry_addr + (_edata - _start);
grub_qemu_init_cirrus ();
#endif
#ifndef GRUB_MACHINE_QEMU
modend = grub_modules_get_end ();
#endif
/* Initialize the console as early as possible. */
grub_vga_text_init ();
#if defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_QEMU)
#ifdef GRUB_MACHINE_MULTIBOOT
grub_machine_mmap_init ();
#endif
grub_machine_mmap_iterate (heap_init, NULL);

View file

@ -0,0 +1,284 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2013 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/>.
*/
#include <grub/kernel.h>
#include <grub/mm.h>
#include <grub/machine/time.h>
#include <grub/machine/memory.h>
#include <grub/machine/console.h>
#include <grub/offsets.h>
#include <grub/types.h>
#include <grub/err.h>
#include <grub/dl.h>
#include <grub/misc.h>
#include <grub/loader.h>
#include <grub/env.h>
#include <grub/cache.h>
#include <grub/time.h>
#include <grub/symbol.h>
#include <grub/cpu/io.h>
#include <grub/cpu/floppy.h>
#include <grub/cpu/tsc.h>
#include <grub/machine/kernel.h>
#include <grub/pci.h>
extern grub_uint8_t _start[];
extern grub_uint8_t _end[];
extern grub_uint8_t _edata[];
void __attribute__ ((noreturn))
grub_exit (void)
{
/* We can't use grub_fatal() in this function. This would create an infinite
loop, since grub_fatal() calls grub_abort() which in turn calls grub_exit(). */
while (1)
grub_cpu_idle ();
}
grub_addr_t grub_modbase;
/* Helper for grub_machine_init. */
static int
heap_init (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type,
void *data __attribute__ ((unused)))
{
grub_uint64_t begin = addr, end = addr + size;
#if GRUB_CPU_SIZEOF_VOID_P == 4
/* Restrict ourselves to 32-bit memory space. */
if (begin > GRUB_ULONG_MAX)
return 0;
if (end > GRUB_ULONG_MAX)
end = GRUB_ULONG_MAX;
#endif
if (type != GRUB_MEMORY_AVAILABLE)
return 0;
/* Avoid the lower memory. */
if (begin < GRUB_MEMORY_MACHINE_LOWER_SIZE)
begin = GRUB_MEMORY_MACHINE_LOWER_SIZE;
if (end <= begin)
return 0;
grub_mm_init_region ((void *) (grub_addr_t) begin, (grub_size_t) (end - begin));
return 0;
}
struct resource
{
grub_pci_device_t dev;
int type;
grub_size_t size;
int bar;
};
struct iterator_ctx
{
struct resource *resources;
grub_size_t nresources;
};
static int
count_cards (grub_pci_device_t dev __attribute__ ((unused)),
grub_pci_id_t pciid __attribute__ ((unused)),
void *data)
{
int *cnt = data;
(*cnt)++;
return 0;
}
static int
find_resources (grub_pci_device_t dev,
grub_pci_id_t pciid __attribute__ ((unused)),
void *data)
{
struct iterator_ctx *ctx = data;
int bar;
for (bar = 0; bar < 6; bar++)
{
grub_pci_address_t addr;
grub_uint32_t ones, zeros, mask;
struct resource *res;
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0
+ 4 * bar);
grub_pci_write (addr, 0xffffffff);
grub_pci_read (addr);
ones = grub_pci_read (addr);
grub_pci_write (addr, 0);
grub_pci_read (addr);
zeros = grub_pci_read (addr);
if (ones == zeros)
continue;
res = &ctx->resources[ctx->nresources++];
if ((zeros & GRUB_PCI_ADDR_SPACE_MASK) == GRUB_PCI_ADDR_SPACE_IO)
mask = GRUB_PCI_ADDR_SPACE_MASK;
else
mask = (GRUB_PCI_ADDR_MEM_TYPE_MASK | GRUB_PCI_ADDR_SPACE_MASK | GRUB_PCI_ADDR_MEM_PREFETCH);
res->type = ones & mask;
res->dev = dev;
res->bar = bar;
res->size = (~((zeros ^ ones)) | mask) + 1;
if ((zeros & (GRUB_PCI_ADDR_MEM_TYPE_MASK | GRUB_PCI_ADDR_SPACE_MASK))
== (GRUB_PCI_ADDR_SPACE_MEMORY | GRUB_PCI_ADDR_MEM_TYPE_64))
bar++;
}
return 0;
}
static int
enable_cards (grub_pci_device_t dev,
grub_pci_id_t pciid __attribute__ ((unused)),
void *data __attribute__ ((unused)))
{
grub_uint16_t cmd = 0;
grub_pci_address_t addr;
grub_uint32_t class;
int bar;
for (bar = 0; bar < 6; bar++)
{
grub_uint32_t val;
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0
+ 4 * bar);
val = grub_pci_read (addr);
if (!val)
continue;
if ((val & GRUB_PCI_ADDR_SPACE_MASK) == GRUB_PCI_ADDR_SPACE_IO)
cmd |= GRUB_PCI_COMMAND_IO_ENABLED;
else
cmd |= GRUB_PCI_COMMAND_MEM_ENABLED;
}
class = (grub_pci_read (addr) >> 16) & 0xffff;
if (class == GRUB_PCI_CLASS_SUBCLASS_VGA)
cmd |= GRUB_PCI_COMMAND_IO_ENABLED
| GRUB_PCI_COMMAND_MEM_ENABLED;
if (class == GRUB_PCI_CLASS_SUBCLASS_USB)
return 0;
addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
grub_pci_write (addr, cmd);
return 0;
}
static void
grub_pci_assign_addresses (void)
{
int ncards = 0;
struct iterator_ctx ctx;
grub_pci_iterate (count_cards, &ncards);
{
struct resource resources[ncards * 6];
int done;
unsigned i;
ctx.nresources = 0;
ctx.resources = resources;
grub_uint32_t memptr = 0xf0000000;
grub_uint16_t ioptr = 0x1000;
grub_pci_iterate (find_resources, &ctx);
/* FIXME: do we need a better sort here? */
do
{
done = 0;
for (i = 0; i + 1 < ctx.nresources; i++)
if (resources[i].size < resources[i+1].size)
{
struct resource t;
t = resources[i];
resources[i] = resources[i+1];
resources[i+1] = t;
done = 1;
}
}
while (done);
for (i = 0; i < ctx.nresources; i++)
{
grub_pci_address_t addr;
addr = grub_pci_make_address (resources[i].dev,
GRUB_PCI_REG_ADDRESS_REG0
+ 4 * resources[i].bar);
if ((resources[i].type & GRUB_PCI_ADDR_SPACE_MASK)
== GRUB_PCI_ADDR_SPACE_IO)
{
grub_pci_write (addr, ioptr | resources[i].type);
ioptr += resources[i].size;
}
else
{
grub_pci_write (addr, memptr | resources[i].type);
memptr += resources[i].size;
if ((resources[i].type & (GRUB_PCI_ADDR_MEM_TYPE_MASK
| GRUB_PCI_ADDR_SPACE_MASK))
== (GRUB_PCI_ADDR_SPACE_MEMORY | GRUB_PCI_ADDR_MEM_TYPE_64))
{
addr = grub_pci_make_address (resources[i].dev,
GRUB_PCI_REG_ADDRESS_REG0
+ 4 * resources[i].bar + 4);
grub_pci_write (addr, 0);
}
}
}
grub_pci_iterate (enable_cards, NULL);
}
}
void
grub_machine_init (void)
{
grub_modbase = grub_core_entry_addr + (_edata - _start);
grub_pci_assign_addresses ();
grub_qemu_init_cirrus ();
grub_vga_text_init ();
grub_machine_mmap_init ();
grub_machine_mmap_iterate (heap_init, NULL);
grub_tsc_init ();
}
void
grub_machine_get_bootlocation (char **device __attribute__ ((unused)),
char **path __attribute__ ((unused)))
{
}
void
grub_machine_fini (void)
{
grub_vga_text_fini ();
grub_stop_floppy ();
}

View file

@ -23,6 +23,9 @@
#include <grub/err.h>
#include <grub/mm.h>
#include <grub/i18n.h>
#include <grub/ia64/reloc.h>
#define MASK19 ((1 << 19) - 1)
/* Check if EHDR is a valid ELF header. */
grub_err_t
@ -41,126 +44,6 @@ grub_arch_dl_check_header (void *ehdr)
#pragma GCC diagnostic ignored "-Wcast-align"
#define MASK20 ((1 << 20) - 1)
#define MASK19 ((1 << 19) - 1)
struct unaligned_uint32
{
grub_uint32_t val;
} __attribute__ ((packed));
static void
add_value_to_slot_20b (grub_addr_t addr, grub_uint32_t value)
{
struct unaligned_uint32 *p;
switch (addr & 3)
{
case 0:
p = (struct unaligned_uint32 *) ((addr & ~3ULL) + 2);
p->val = ((((((p->val >> 2) & MASK20) + value) & MASK20) << 2)
| (p->val & ~(MASK20 << 2)));
break;
case 1:
p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & ~3ULL) + 7);
p->val = ((((((p->val >> 3) & MASK20) + value) & MASK20) << 3)
| (p->val & ~(MASK20 << 3)));
break;
case 2:
p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & ~3ULL) + 12);
p->val = ((((((p->val >> 4) & MASK20) + value) & MASK20) << 4)
| (p->val & ~(MASK20 << 4)));
break;
}
}
#define MASKF21 ( ((1 << 23) - 1) & ~((1 << 7) | (1 << 8)) )
static grub_uint32_t
add_value_to_slot_21_real (grub_uint32_t a, grub_uint32_t value)
{
grub_uint32_t high, mid, low, c;
low = (a & 0x00007f);
mid = (a & 0x7fc000) >> 7;
high = (a & 0x003e00) << 7;
c = (low | mid | high) + value;
return (c & 0x7f) | ((c << 7) & 0x7fc000) | ((c >> 7) & 0x0003e00); //0x003e00
}
static void
add_value_to_slot_21 (grub_addr_t addr, grub_uint32_t value)
{
struct unaligned_uint32 *p;
switch (addr & 3)
{
case 0:
p = (struct unaligned_uint32 *) ((addr & ~3ULL) + 2);
p->val = ((add_value_to_slot_21_real (((p->val >> 2) & MASKF21), value) & MASKF21) << 2) | (p->val & ~(MASKF21 << 2));
break;
case 1:
p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & ~3ULL) + 7);
p->val = ((add_value_to_slot_21_real (((p->val >> 3) & MASKF21), value) & MASKF21) << 3) | (p->val & ~(MASKF21 << 3));
break;
case 2:
p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & ~3ULL) + 12);
p->val = ((add_value_to_slot_21_real (((p->val >> 4) & MASKF21), value) & MASKF21) << 4) | (p->val & ~(MASKF21 << 4));
break;
}
}
static const grub_uint8_t nopm[5] =
{
/* [MLX] nop.m 0x0 */
0x05, 0x00, 0x00, 0x00, 0x01
};
static const grub_uint8_t jump[0x20] =
{
/* ld8 r16=[r15],8 */
0x02, 0x80, 0x20, 0x1e, 0x18, 0x14,
/* mov r14=r1;; */
0xe0, 0x00, 0x04, 0x00, 0x42, 0x00,
/* nop.i 0x0 */
0x00, 0x00, 0x04, 0x00,
/* ld8 r1=[r15] */
0x11, 0x08, 0x00, 0x1e, 0x18, 0x10,
/* mov b6=r16 */
0x60, 0x80, 0x04, 0x80, 0x03, 0x00,
/* br.few b6;; */
0x60, 0x00, 0x80, 0x00
};
struct ia64_trampoline
{
/* nop.m */
grub_uint8_t nop[5];
/* movl r15 = addr*/
grub_uint8_t addr_hi[6];
grub_uint8_t e0;
grub_uint8_t addr_lo[4];
grub_uint8_t jump[0x20];
};
static void
make_trampoline (struct ia64_trampoline *tr, grub_uint64_t addr)
{
COMPILE_TIME_ASSERT (sizeof (struct ia64_trampoline)
== GRUB_IA64_DL_TRAMP_SIZE);
grub_memcpy (tr->nop, nopm, sizeof (tr->nop));
tr->addr_hi[0] = ((addr & 0xc00000) >> 16);
tr->addr_hi[1] = (addr >> 24) & 0xff;
tr->addr_hi[2] = (addr >> 32) & 0xff;
tr->addr_hi[3] = (addr >> 40) & 0xff;
tr->addr_hi[4] = (addr >> 48) & 0xff;
tr->addr_hi[5] = (addr >> 56) & 0xff;
tr->e0 = 0xe0;
tr->addr_lo[0] = ((addr & 0x000f) << 4) | 0x01;
tr->addr_lo[1] = (((addr & 0x0070) >> 4) | ((addr & 0x070000) >> 11)
| ((addr & 0x200000) >> 17));
tr->addr_lo[2] = ((addr & 0x1f80) >> 5) | ((addr & 0x180000) >> 19);
tr->addr_lo[3] = ((addr & 0xe000) >> 13) | 0x60;
grub_memcpy (tr->jump, jump, sizeof (tr->jump));
}
/* Relocate symbols. */
grub_err_t
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
@ -170,7 +53,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
Elf_Word entsize;
unsigned i;
grub_uint64_t *gp, *gpptr;
struct ia64_trampoline *tr;
struct grub_ia64_trampoline *tr;
gp = (grub_uint64_t *) mod->base;
gpptr = (grub_uint64_t *) mod->got;
@ -230,13 +113,13 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
case R_IA64_PCREL21B:
{
grub_uint64_t noff;
make_trampoline (tr, value);
grub_ia64_make_trampoline (tr, value);
noff = ((char *) tr - (char *) (addr & ~3)) >> 4;
tr++;
tr = (struct grub_ia64_trampoline *) ((char *) tr + GRUB_IA64_DL_TRAMP_SIZE);
if (noff & ~MASK19)
return grub_error (GRUB_ERR_BAD_OS,
"trampoline offset too big (%lx)", noff);
add_value_to_slot_20b (addr, noff);
grub_ia64_add_value_to_slot_20b (addr, noff);
}
break;
case R_IA64_SEGREL64LSB:
@ -250,7 +133,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
*(grub_uint64_t *) addr += value - addr;
break;
case R_IA64_GPREL22:
add_value_to_slot_21 (addr, value - (grub_addr_t) gp);
grub_ia64_add_value_to_slot_21 (addr, value - (grub_addr_t) gp);
break;
case R_IA64_LTOFF22X:
@ -259,7 +142,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
value = *(grub_uint64_t *) sym->st_value + rel->r_addend;
case R_IA64_LTOFF_FPTR22:
*gpptr = value;
add_value_to_slot_21 (addr, (grub_addr_t) gpptr - (grub_addr_t) gp);
grub_ia64_add_value_to_slot_21 (addr, (grub_addr_t) gpptr - (grub_addr_t) gp);
gpptr++;
break;

View file

@ -22,9 +22,154 @@
#include <grub/misc.h>
#include <grub/err.h>
#include <grub/mm.h>
#include <grub/i18n.h>
#include <grub/ia64/reloc.h>
#pragma GCC diagnostic ignored "-Wcast-align"
#define MASK20 ((1 << 20) - 1)
#define MASK3 (~(grub_addr_t) 3)
void
grub_ia64_add_value_to_slot_20b (grub_addr_t addr, grub_uint32_t value)
{
grub_uint32_t val;
switch (addr & 3)
{
case 0:
val = grub_le_to_cpu32 (grub_get_unaligned32 (((grub_uint8_t *)
(addr & MASK3) + 2)));
val = (((((val & MASK20) + value) & MASK20) << 2)
| (val & ~(MASK20 << 2)));
grub_set_unaligned32 (((grub_uint8_t *) (addr & MASK3) + 2),
grub_cpu_to_le32 (val));
break;
case 1:
val = grub_le_to_cpu32 (grub_get_unaligned32 (((grub_uint8_t *)
(addr & MASK3) + 7)));
val = ((((((val >> 3) & MASK20) + value) & MASK20) << 3)
| (val & ~(MASK20 << 3)));
grub_set_unaligned32 (((grub_uint8_t *) (addr & MASK3) + 7),
grub_cpu_to_le32 (val));
break;
case 2:
val = grub_le_to_cpu32 (grub_get_unaligned32 (((grub_uint8_t *)
(addr & MASK3) + 12)));
val = ((((((val >> 4) & MASK20) + value) & MASK20) << 4)
| (val & ~(MASK20 << 4)));
grub_set_unaligned32 (((grub_uint8_t *) (addr & MASK3) + 12),
grub_cpu_to_le32 (val));
break;
}
}
#define MASKF21 ( ((1 << 23) - 1) & ~((1 << 7) | (1 << 8)) )
static grub_uint32_t
add_value_to_slot_21_real (grub_uint32_t a, grub_uint32_t value)
{
grub_uint32_t high, mid, low, c;
low = (a & 0x00007f);
mid = (a & 0x7fc000) >> 7;
high = (a & 0x003e00) << 7;
c = (low | mid | high) + value;
return (c & 0x7f) | ((c << 7) & 0x7fc000) | ((c >> 7) & 0x0003e00); //0x003e00
}
void
grub_ia64_add_value_to_slot_21 (grub_addr_t addr, grub_uint32_t value)
{
grub_uint32_t val;
switch (addr & 3)
{
case 0:
val = grub_le_to_cpu32 (grub_get_unaligned32 (((grub_uint8_t *)
(addr & MASK3) + 2)));
val = ((add_value_to_slot_21_real (((val >> 2) & MASKF21), value)
& MASKF21) << 2) | (val & ~(MASKF21 << 2));
grub_set_unaligned32 (((grub_uint8_t *) (addr & MASK3) + 2),
grub_cpu_to_le32 (val));
break;
case 1:
val = grub_le_to_cpu32 (grub_get_unaligned32 (((grub_uint8_t *)
(addr & MASK3) + 7)));
val = ((add_value_to_slot_21_real (((val >> 3) & MASKF21), value)
& MASKF21) << 3) | (val & ~(MASKF21 << 3));
grub_set_unaligned32 (((grub_uint8_t *) (addr & MASK3) + 7),
grub_cpu_to_le32 (val));
break;
case 2:
val = grub_le_to_cpu32 (grub_get_unaligned32 (((grub_uint8_t *)
(addr & MASK3) + 12)));
val = ((add_value_to_slot_21_real (((val >> 4) & MASKF21), value)
& MASKF21) << 4) | (val & ~(MASKF21 << 4));
grub_set_unaligned32 (((grub_uint8_t *) (addr & MASK3) + 12),
grub_cpu_to_le32 (val));
break;
}
}
static const grub_uint8_t nopm[5] =
{
/* [MLX] nop.m 0x0 */
0x05, 0x00, 0x00, 0x00, 0x01
};
#ifdef GRUB_UTIL
static grub_uint8_t jump[0x20] =
{
/* [MMI] add r15=r15,r1;; */
0x0b, 0x78, 0x3c, 0x02, 0x00, 0x20,
/* ld8 r16=[r15],8 */
0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0,
/* mov r14=r1;; */
0x01, 0x08, 0x00, 0x84,
/* [MIB] ld8 r1=[r15] */
0x11, 0x08, 0x00, 0x1e, 0x18, 0x10,
/* mov b6=r16 */
0x60, 0x80, 0x04, 0x80, 0x03, 0x00,
/* br.few b6;; */
0x60, 0x00, 0x80, 0x00
};
#else
static const grub_uint8_t jump[0x20] =
{
/* ld8 r16=[r15],8 */
0x02, 0x80, 0x20, 0x1e, 0x18, 0x14,
/* mov r14=r1;; */
0xe0, 0x00, 0x04, 0x00, 0x42, 0x00,
/* nop.i 0x0 */
0x00, 0x00, 0x04, 0x00,
/* ld8 r1=[r15] */
0x11, 0x08, 0x00, 0x1e, 0x18, 0x10,
/* mov b6=r16 */
0x60, 0x80, 0x04, 0x80, 0x03, 0x00,
/* br.few b6;; */
0x60, 0x00, 0x80, 0x00
};
#endif
void
grub_ia64_make_trampoline (struct grub_ia64_trampoline *tr, grub_uint64_t addr)
{
COMPILE_TIME_ASSERT (sizeof (struct grub_ia64_trampoline)
== GRUB_IA64_DL_TRAMP_SIZE);
grub_memcpy (tr->nop, nopm, sizeof (tr->nop));
tr->addr_hi[0] = ((addr & 0xc00000) >> 16);
tr->addr_hi[1] = (addr >> 24) & 0xff;
tr->addr_hi[2] = (addr >> 32) & 0xff;
tr->addr_hi[3] = (addr >> 40) & 0xff;
tr->addr_hi[4] = (addr >> 48) & 0xff;
tr->addr_hi[5] = (addr >> 56) & 0xff;
tr->e0 = 0xe0;
tr->addr_lo[0] = ((addr & 0x000f) << 4) | 0x01;
tr->addr_lo[1] = (((addr & 0x0070) >> 4) | ((addr & 0x070000) >> 11)
| ((addr & 0x200000) >> 17));
tr->addr_lo[2] = ((addr & 0x1f80) >> 5) | ((addr & 0x180000) >> 19);
tr->addr_lo[3] = ((addr & 0xe000) >> 13) | 0x60;
grub_memcpy (tr->jump, jump, sizeof (tr->jump));
}
void
grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
grub_size_t *got)
@ -35,26 +180,26 @@ grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
unsigned i;
/* Find a symbol table. */
for (i = 0, s = (Elf64_Shdr *) ((char *) e + grub_le_to_cpu32 (e->e_shoff));
for (i = 0, s = (Elf64_Shdr *) ((char *) e + grub_le_to_cpu64 (e->e_shoff));
i < grub_le_to_cpu16 (e->e_shnum);
i++, s = (Elf64_Shdr *) ((char *) s + grub_le_to_cpu16 (e->e_shentsize)))
if (grub_le_to_cpu32 (s->sh_type) == SHT_SYMTAB)
if (s->sh_type == grub_cpu_to_le32_compile_time (SHT_SYMTAB))
break;
if (i == grub_le_to_cpu16 (e->e_shnum))
return;
for (i = 0, s = (Elf64_Shdr *) ((char *) e + grub_le_to_cpu32 (e->e_shoff));
for (i = 0, s = (Elf64_Shdr *) ((char *) e + grub_le_to_cpu64 (e->e_shoff));
i < grub_le_to_cpu16 (e->e_shnum);
i++, s = (Elf64_Shdr *) ((char *) s + grub_le_to_cpu16 (e->e_shentsize)))
if (grub_le_to_cpu32 (s->sh_type) == SHT_RELA)
if (s->sh_type == grub_cpu_to_le32_compile_time (SHT_RELA))
{
Elf64_Rela *rel, *max;
for (rel = (Elf64_Rela *) ((char *) e + grub_le_to_cpu32 (s->sh_offset)),
max = rel + grub_le_to_cpu32 (s->sh_size) / grub_le_to_cpu16 (s->sh_entsize);
for (rel = (Elf64_Rela *) ((char *) e + grub_le_to_cpu64 (s->sh_offset)),
max = rel + grub_le_to_cpu64 (s->sh_size) / grub_le_to_cpu64 (s->sh_entsize);
rel < max; rel++)
switch (ELF64_R_TYPE (grub_le_to_cpu32 (rel->r_info)))
switch (ELF64_R_TYPE (grub_le_to_cpu64 (rel->r_info)))
{
case R_IA64_PCREL21B:
cntt++;

View file

@ -43,9 +43,6 @@ grub_ieee1275_set_flag (enum grub_ieee1275_flag flag)
grub_ieee1275_flags |= (1 << flag);
}
#define SF "SmartFirmware(tm)"
#define OHW "PPC Open Hack'Ware"
static void
grub_ieee1275_find_options (void)
{
@ -76,7 +73,8 @@ grub_ieee1275_find_options (void)
rc = grub_ieee1275_get_property (openprom, "CodeGen-copyright",
tmp, sizeof (tmp), 0);
if (rc >= 0 && !grub_strncmp (tmp, SF, sizeof (SF) - 1))
if (rc >= 0 && !grub_strncmp (tmp, "SmartFirmware(tm)",
sizeof ("SmartFirmware(tm)") - 1))
is_smartfirmware = 1;
rc = grub_ieee1275_get_property (root, "architecture",
@ -188,10 +186,12 @@ grub_ieee1275_find_options (void)
grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_HAS_CURSORONOFF);
}
if (! grub_ieee1275_finddevice ("/rom/boot-rom", &bootrom))
if (! grub_ieee1275_finddevice ("/rom/boot-rom", &bootrom)
|| ! grub_ieee1275_finddevice ("/boot-rom", &bootrom))
{
rc = grub_ieee1275_get_property (bootrom, "model", tmp, sizeof (tmp), 0);
if (rc >= 0 && !grub_strncmp (tmp, OHW, sizeof (OHW) - 1))
if (rc >= 0 && !grub_strncmp (tmp, "PPC Open Hack'Ware",
sizeof ("PPC Open Hack'Ware") - 1))
{
grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_OUTPUT);
grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_CANNOT_SET_COLORS);
@ -202,9 +202,6 @@ grub_ieee1275_find_options (void)
}
}
#undef SF
#undef OHW
void
grub_ieee1275_init (void)
{

View file

@ -225,8 +225,9 @@ grub_claim_heap (void)
{
unsigned long total = 0;
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET))
heap_init (HEAP_MAX_ADDR - HEAP_MIN_SIZE, HEAP_MIN_SIZE, 1, &total);
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_FORCE_CLAIM))
heap_init (GRUB_IEEE1275_STATIC_HEAP_START, GRUB_IEEE1275_STATIC_HEAP_LEN,
1, &total);
else
grub_machine_mmap_iterate (heap_init, &total);
}

View file

@ -193,18 +193,22 @@ grub_ieee1275_devalias_next (struct grub_ieee1275_devalias *alias)
{
grub_ssize_t pathlen;
grub_ssize_t actual;
char *tmp;
if (alias->path)
{
grub_free (alias->path);
alias->path = 0;
}
if (grub_ieee1275_next_property (alias->parent_dev, alias->name,
tmp = grub_strdup (alias->name);
if (grub_ieee1275_next_property (alias->parent_dev, tmp,
alias->name) <= 0)
{
grub_free (tmp);
grub_ieee1275_devalias_free (alias);
return 0;
}
grub_free (tmp);
grub_dprintf ("devalias", "devalias name = %s\n", alias->name);

View file

@ -34,6 +34,8 @@
#include <grub/arc/arc.h>
#include <grub/offsets.h>
#include <grub/i18n.h>
#include <grub/disk.h>
#include <grub/partition.h>
const char *type_names[] = {
#ifdef GRUB_CPU_WORDS_BIGENDIAN
@ -43,7 +45,11 @@ const char *type_names[] = {
"eisa", "tc", "scsi", "dti", "multi", "disk", "tape", "cdrom", "worm",
"serial", "net", "video", "par", "point", "key", "audio", "other",
"rdisk", "fdisk", "tape", "modem", "monitor", "print", "pointer",
"keyboard", "term", "other", "line", "network", NULL
"keyboard", "term",
#ifndef GRUB_CPU_WORDS_BIGENDIAN
"other",
#endif
"line", "network", NULL
};
static int
@ -125,15 +131,100 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
}
}
char *
grub_arc_alt_name_to_norm (const char *name, const char *suffix)
{
char *optr;
const char *iptr;
char * ret = grub_malloc (2 * grub_strlen (name) + grub_strlen (suffix));
int state = 0;
if (!ret)
return NULL;
optr = ret;
for (iptr = name + 4; *iptr; iptr++)
if (state == 0)
{
if (!grub_isdigit (*iptr))
*optr++ = *iptr;
else
{
*optr++ = '(';
*optr++ = *iptr;
state = 1;
}
}
else
{
if (grub_isdigit (*iptr))
*optr++ = *iptr;
else
{
*optr++ = ')';
state = 0;
}
}
if (state)
*optr++ = ')';
grub_strcpy (optr, suffix);
return ret;
}
static char *
norm_name_to_alt (const char *name)
{
char *optr;
const char *iptr;
int state = 0;
char * ret = grub_malloc (grub_strlen (name) + sizeof ("arc/"));
if (!ret)
return NULL;
optr = grub_stpcpy (ret, "arc/");
for (iptr = name; *iptr; iptr++)
{
if (state == 3)
{
*optr++ = '/';
state = 0;
}
if (*iptr == '(')
{
state = 1;
continue;
}
if (*iptr == ')')
{
if (state == 1)
*optr++ = '0';
state = 3;
continue;
}
*optr++ = *iptr;
if (state == 1)
state = 2;
}
*optr = '\0';
return ret;
}
extern grub_uint32_t grub_total_modules_size __attribute__ ((section(".text")));
grub_addr_t grub_modbase;
extern char _end[];
static char boot_location[256];
void
grub_machine_init (void)
{
struct grub_arc_memory_descriptor *cur = NULL;
grub_addr_t modend;
grub_modbase = GRUB_KERNEL_MIPS_ARC_LINK_ADDR - grub_total_modules_size;
grub_memcpy (boot_location,
(char *) (GRUB_DECOMPRESSOR_LINK_ADDR - 256), 256);
grub_modbase = ALIGN_UP ((grub_addr_t) _end, GRUB_KERNEL_MACHINE_MOD_ALIGN);
modend = grub_modbase + grub_total_modules_size;
grub_console_init_early ();
/* FIXME: measure this. */
@ -153,10 +244,10 @@ grub_machine_init (void)
start = ((grub_uint64_t) cur->start_page) << 12;
end = ((grub_uint64_t) cur->num_pages) << 12;
end += start;
if ((grub_uint64_t) end > ((GRUB_KERNEL_MIPS_ARC_LINK_ADDR
- grub_total_modules_size) & 0x1fffffff))
end = ((GRUB_KERNEL_MIPS_ARC_LINK_ADDR - grub_total_modules_size)
& 0x1fffffff);
if ((grub_uint64_t) start < (modend & 0x1fffffff))
start = (modend & 0x1fffffff);
if ((grub_uint64_t) end > 0x20000000)
end = 0x20000000;
if (end > start)
grub_mm_init_region ((void *) (grub_addr_t) (start | 0x80000000),
end - start);
@ -196,3 +287,178 @@ grub_exit (void)
while (1);
}
static char *
get_part (char *dev)
{
char *ptr;
if (!*dev)
return 0;
ptr = dev + grub_strlen (dev) - 1;
if (ptr == dev || *ptr != ')')
return 0;
ptr--;
while (grub_isdigit (*ptr) && ptr > dev)
ptr--;
if (*ptr != '(' || ptr == dev)
return 0;
ptr--;
if (ptr - dev < (int) sizeof ("partition") - 2)
return 0;
ptr -= sizeof ("partition") - 2;
if (grub_memcmp (ptr, "partition", sizeof ("partition") - 1) != 0)
return 0;
return ptr;
}
static grub_disk_addr_t
get_partition_offset (char *part, grub_disk_addr_t *en)
{
grub_arc_fileno_t handle;
grub_disk_addr_t ret = -1;
struct grub_arc_fileinfo info;
grub_arc_err_t r;
if (GRUB_ARC_FIRMWARE_VECTOR->open (part, GRUB_ARC_FILE_ACCESS_OPEN_RO,
&handle))
return -1;
r = GRUB_ARC_FIRMWARE_VECTOR->getfileinformation (handle, &info);
if (!r)
{
ret = (info.start >> 9);
*en = (info.end >> 9);
}
GRUB_ARC_FIRMWARE_VECTOR->close (handle);
return ret;
}
struct get_device_name_ctx
{
char *partition_name;
grub_disk_addr_t poff, pend;
};
static int
get_device_name_iter (grub_disk_t disk __attribute__ ((unused)),
const grub_partition_t part, void *data)
{
struct get_device_name_ctx *ctx = data;
if (grub_partition_get_start (part) == ctx->poff
&& grub_partition_get_len (part) == ctx->pend)
{
ctx->partition_name = grub_partition_get_name (part);
return 1;
}
return 0;
}
void
grub_machine_get_bootlocation (char **device __attribute__ ((unused)),
char **path __attribute__ ((unused)))
{
char *loaddev = boot_location;
char *pptr, *partptr;
char *dname;
grub_disk_addr_t poff = -1, pend;
struct get_device_name_ctx ctx;
grub_disk_t parent = 0;
unsigned i;
for (i = 0; i < ARRAY_SIZE (type_names); i++)
if (type_names[i]
&& grub_memcmp (loaddev, type_names[i], grub_strlen (type_names[i])) == 0
&& loaddev[grub_strlen (type_names[i])] == '(')
break;
if (i == ARRAY_SIZE (type_names))
pptr = loaddev;
else
for (pptr = loaddev; *pptr && *pptr != '/' && *pptr != '\\'; pptr++);
if (*pptr)
{
char *iptr, *optr;
char sep = *pptr;
*path = grub_malloc (grub_strlen (pptr) + 1);
if (!*path)
return;
for (iptr = pptr, optr = *path; *iptr; iptr++, optr++)
if (*iptr == sep)
*optr = '/';
else
*optr = *iptr;
*optr = '\0';
*path = grub_strdup (pptr);
*pptr = '\0';
}
if (*loaddev == '\0')
{
const char *syspart = 0;
if (GRUB_ARC_SYSTEM_PARAMETER_BLOCK->firmware_vector_length
>= ((char *) (&GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable + 1)
- (char *) GRUB_ARC_FIRMWARE_VECTOR)
&& GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable)
syspart = GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable ("SystemPartition");
if (!syspart)
return;
loaddev = grub_strdup (syspart);
}
partptr = get_part (loaddev);
if (partptr)
{
poff = get_partition_offset (loaddev, &pend);
*partptr = '\0';
}
dname = norm_name_to_alt (loaddev);
if (poff == (grub_addr_t) -1)
{
*device = dname;
if (loaddev != boot_location)
grub_free (loaddev);
return;
}
parent = grub_disk_open (dname);
if (!parent)
{
*device = dname;
if (loaddev != boot_location)
grub_free (loaddev);
return;
}
if (poff == 0
&& pend == grub_disk_get_size (parent))
{
grub_disk_close (parent);
*device = dname;
if (loaddev != boot_location)
grub_free (loaddev);
return;
}
ctx.partition_name = NULL;
ctx.poff = poff;
ctx.pend = pend;
grub_partition_iterate (parent, get_device_name_iter, &ctx);
grub_disk_close (parent);
if (! ctx.partition_name)
{
*device = dname;
if (loaddev != boot_location)
grub_free (loaddev);
return;
}
*device = grub_xasprintf ("%s,%s", dname,
ctx.partition_name);
grub_free (ctx.partition_name);
grub_free (dname);
if (loaddev != boot_location)
grub_free (loaddev);
}

View file

@ -36,9 +36,3 @@ grub_get_rtc (void)
return (((grub_uint64_t) high) << 32) | low;
}
void
grub_machine_get_bootlocation (char **device __attribute__ ((unused)),
char **path __attribute__ ((unused)))
{
}

View file

@ -55,7 +55,8 @@ set_card (grub_pci_device_t dev, grub_pci_id_t pciid,
void *data __attribute__ ((unused)))
{
grub_pci_address_t addr;
/* FIXME: autoscan for BARs and devices. */
/* We could use grub_pci_assign_addresses for this but we prefer to
have exactly same memory map as on pmon. */
switch (pciid)
{
case GRUB_LOONGSON_OHCI_PCIID:
@ -220,12 +221,45 @@ grub_machine_fini (void)
{
}
static int
halt_via (grub_pci_device_t dev, grub_pci_id_t pciid,
void *data __attribute__ ((unused)))
{
grub_uint16_t pm;
grub_pci_address_t addr;
if (pciid != 0x30571106)
return 0;
addr = grub_pci_make_address (dev, 0x40);
pm = grub_pci_read (addr) & ~1;
if (pm == 0)
{
grub_pci_write (addr, 0x1801);
pm = 0x1800;
}
addr = grub_pci_make_address (dev, 0x80);
grub_pci_write_byte (addr, 0xff);
addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
grub_pci_write_word (addr, grub_pci_read_word (addr) | GRUB_PCI_COMMAND_IO_ENABLED);
/* FIXME: This one is derived from qemu. Check on real hardware. */
grub_outw (0x2000, pm + 4 + GRUB_MACHINE_PCI_IO_BASE);
grub_millisleep (5000);
return 0;
}
void
grub_halt (void)
{
switch (grub_arch_machine)
{
case GRUB_ARCH_MACHINE_FULOONG2E:
grub_pci_iterate (halt_via, NULL);
break;
case GRUB_ARCH_MACHINE_FULOONG2F:
{
@ -259,6 +293,12 @@ grub_exit (void)
grub_halt ();
}
void
grub_machine_get_bootlocation (char **device __attribute__ ((unused)),
char **path __attribute__ ((unused)))
{
}
extern char _end[];
grub_addr_t grub_modbase = (grub_addr_t) _end;

View file

@ -98,6 +98,12 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
return GRUB_ERR_NONE;
}
void
grub_machine_get_bootlocation (char **device __attribute__ ((unused)),
char **path __attribute__ ((unused)))
{
}
extern char _end[];
grub_addr_t grub_modbase = (grub_addr_t) _end;

View file

@ -73,7 +73,6 @@ cont:
#endif
/* Move the modules out of BSS. */
#ifndef GRUB_MACHINE_ARC
lui $t2, %hi(__bss_start)
addiu $t2, %lo(__bss_start)
@ -103,7 +102,6 @@ modulesmovcont:
b modulesmovcont
addiu $t3, $t3, -1
modulesmovdone:
#endif
/* Clean BSS. */

View file

@ -140,12 +140,13 @@ grub_mm_init_region (void *addr, grub_size_t size)
/* Allocate a region from the head. */
r = (grub_mm_region_t) ALIGN_UP ((grub_addr_t) addr, GRUB_MM_ALIGN);
size -= (char *) r - (char *) addr + sizeof (*r);
/* If this region is too small, ignore it. */
if (size < GRUB_MM_ALIGN)
if (size < GRUB_MM_ALIGN + (char *) r - (char *) addr + sizeof (*r))
return;
size -= (char *) r - (char *) addr + sizeof (*r);
h = (grub_mm_header_t) (r + 1);
h->next = h;
h->magic = GRUB_MM_FREE_MAGIC;

View file

@ -46,7 +46,6 @@ grub_putcode_dumb (grub_uint32_t code,
.variant = 0,
.attributes = 0,
.ncomb = 0,
.combining = 0,
.estimated_width = 1
};

View file

@ -88,44 +88,9 @@ load_palette (void)
grub_vga_palette_write (i, colors[i].r, colors[i].g, colors[i].b);
}
#ifndef __mips__
/* Helper for grub_qemu_init_cirrus. */
static int
find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused)),
void *data __attribute__ ((unused)))
{
grub_pci_address_t addr;
grub_uint32_t class;
addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
class = grub_pci_read (addr);
if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA)
return 0;
/* FIXME: chooose addresses dynamically. */
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
grub_pci_write (addr, 0xf0000000 | GRUB_PCI_ADDR_MEM_PREFETCH
| GRUB_PCI_ADDR_SPACE_MEMORY | GRUB_PCI_ADDR_MEM_TYPE_32);
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG1);
grub_pci_write (addr, 0xf2000000
| GRUB_PCI_ADDR_SPACE_MEMORY | GRUB_PCI_ADDR_MEM_TYPE_32);
addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
grub_pci_write (addr, GRUB_PCI_COMMAND_MEM_ENABLED
| GRUB_PCI_COMMAND_IO_ENABLED);
return 1;
}
#endif
void
grub_qemu_init_cirrus (void)
{
#ifndef __mips__
grub_pci_iterate (find_card, NULL);
#endif
grub_outb (GRUB_VGA_IO_MISC_COLOR,
GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_MISC_WRITE);