Implement grub_machine_get_bootlocation for ARC.

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2013-04-27 19:12:11 +02:00
parent dc2a6c8b0e
commit 17f9fd29d3
8 changed files with 207 additions and 9 deletions

View File

@ -1,3 +1,7 @@
2013-04-27 Vladimir Serbinenko <phcoder@gmail.com>
Implement grub_machine_get_bootlocation for ARC.
2013-04-27 Vladimir Serbinenko <phcoder@gmail.com>
Improve AHCI detection and command issuing.

View File

@ -76,6 +76,7 @@ kernel = {
mips_arc_ldflags = '-Wl,-Ttext,$(TARGET_LINK_ADDR)';
mips_qemu_mips_ldflags = '-Wl,-Ttext,0x80200000';
mips_arc_cppflags = '-DGRUB_DECOMPRESSOR_LINK_ADDR=$(TARGET_DECOMPRESSOR_LINK_ADDR)';
mips_loongson_cppflags = '-DUSE_ASCII_FAILBACK';
i386_qemu_cppflags = '-DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)';
emu_cflags = '$(CFLAGS_GNULIB)';

View File

@ -196,6 +196,21 @@ do_check:
argfw:
not $s7, $a2
cmdlinedone:
#endif
#ifdef GRUB_MACHINE_ARC
lui $t0, %hi(_start - 256)
addiu $t0, $t0, %lo(_start - 256)
addiu $t3, $t0, 255
lw $t1, 0($a1)
1:
bne $t0, $t3, 2f
lb $t2, 0($t1)
move $t2, $zero
2:
sb $t2, 0($t0)
addiu $t0, $t0, 1
bnez $t2, 1b
addiu $t1, $t1, 1
#endif
/* Copy the decompressor. */
lui $t1, %hi(base)
@ -253,10 +268,15 @@ cmdlinedone:
lui $t0, %hi(EXT_C(grub_decompress_core))
addiu $t0, $t0, %lo(EXT_C(grub_decompress_core))
#ifdef GRUB_MACHINE_ARC
lui $sp, %hi(_start - 512)
jalr $t0
addiu $sp, $sp, %lo(_start - 512)
#else
lui $sp, %hi(_start - 256)
jalr $t0
addiu $sp, $sp, %lo(_start - 256)
#endif
move $a0, $s1
move $a1, $s6

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
@ -164,10 +166,42 @@ grub_arc_alt_name_to_norm (const char *name, const char *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 == 1)
{
*optr++ = '/';
state = 0;
}
if (*iptr == '(')
continue;
if (*iptr == ')')
{
state = 1;
continue;
}
*optr++ = *iptr;
}
*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)
@ -175,6 +209,9 @@ grub_machine_init (void)
struct grub_arc_memory_descriptor *cur = NULL;
grub_addr_t modend;
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 ();
@ -239,3 +276,133 @@ 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;
pptr = grub_strchr (loaddev, '/');
if (pptr)
{
*path = grub_strdup (pptr);
*pptr = '\0';
}
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;
return;
}
parent = grub_disk_open (dname);
if (!parent)
{
*device = dname;
return;
}
if (poff == 0
&& pend == grub_disk_get_size (parent))
{
grub_disk_close (parent);
*device = dname;
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;
return;
}
*device = grub_xasprintf ("%s,%s", dname,
ctx.partition_name);
grub_free (ctx.partition_name);
grub_free (dname);
}

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

@ -259,6 +259,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

@ -489,7 +489,7 @@ if [ -e "${iso9660_dir}"/boot/grub/sparc64-ieee1275/core.img ] && [ "$system_are
grub_mkisofs_arguments="${grub_mkisofs_arguments} -G $sysarea_img -B , --grub2-sparc-core /boot/grub/sparc64-ieee1275/core.img"
fi
make_image "${arcs_dir}" mips-arc "${iso9660_dir}/boot/grub/mips-arc/core.img" ""
make_image_fwdisk "${arcs_dir}" mips-arc "${iso9660_dir}/boot/grub/mips-arc/core.img" ""
if [ -e "${iso9660_dir}/boot/grub/mips-arc/core.img" ]; then
grub_mkisofs_arguments="${grub_mkisofs_arguments} /boot/grub/mips-arc/grub=${iso9660_dir}/boot/grub/mips-arc/core.img /boot/grub/mips-arc/sashARCS=${iso9660_dir}/boot/grub/mips-arc/core.img /boot/grub/mips-arc/sash=${iso9660_dir}/boot/grub/mips-arc/core.img"
fi
@ -497,7 +497,7 @@ if [ -e "${iso9660_dir}/boot/grub/mips-arc/core.img" ] && [ "$system_area" = arc
grub_mkisofs_arguments="${grub_mkisofs_arguments} -mips-boot /boot/grub/mips-arc/sashARCS -mips-boot /boot/grub/mips-arc/sash -mips-boot /boot/grub/mips-arc/grub"
fi
make_image "${arc_dir}" mipsel-arc "${iso9660_dir}/boot/grub/arc.exe" ""
make_image_fwdisk "${arc_dir}" mipsel-arc "${iso9660_dir}/boot/grub/arc.exe" ""
make_image "${mipsel_qemu_dir}" mipsel-qemu_mips-elf "${iso9660_dir}/boot/grub/roms/mipsel-qemu_mips.elf" "pata"
if [ -e "${iso9660_dir}/boot/grub/roms/mipsel-qemu_mips.elf" ] && [ -d "${rom_directory}" ]; then