From 081e3821a7800ef03e67788efd60fc86f18e645d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 27 Apr 2013 19:12:11 +0200 Subject: [PATCH 363/471] Implement grub_machine_get_bootlocation for ARC. --- ChangeLog | 4 + grub-core/Makefile.core.def | 1 + grub-core/boot/mips/startup_raw.S | 22 ++++- grub-core/kern/mips/arc/init.c | 167 +++++++++++++++++++++++++++++++++++ grub-core/kern/mips/init.c | 6 -- grub-core/kern/mips/loongson/init.c | 6 ++ grub-core/kern/mips/qemu_mips/init.c | 6 ++ util/grub-mkrescue.in | 4 +- 8 files changed, 207 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0d4329c..09a6c70 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2013-04-27 Vladimir Serbinenko + Implement grub_machine_get_bootlocation for ARC. + +2013-04-27 Vladimir Serbinenko + Improve AHCI detection and command issuing. 2013-04-26 Vladimir Serbinenko diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 2a8ac6f..7f93723 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -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)'; diff --git a/grub-core/boot/mips/startup_raw.S b/grub-core/boot/mips/startup_raw.S index bbbc1db..6061976 100644 --- a/grub-core/boot/mips/startup_raw.S +++ b/grub-core/boot/mips/startup_raw.S @@ -197,6 +197,21 @@ 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) addiu $t1, $t1, %lo(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 diff --git a/grub-core/kern/mips/arc/init.c b/grub-core/kern/mips/arc/init.c index 92a2877..d279ada 100644 --- a/grub-core/kern/mips/arc/init.c +++ b/grub-core/kern/mips/arc/init.c @@ -34,6 +34,8 @@ #include #include #include +#include +#include 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); +} diff --git a/grub-core/kern/mips/init.c b/grub-core/kern/mips/init.c index 353f679..14b8752 100644 --- a/grub-core/kern/mips/init.c +++ b/grub-core/kern/mips/init.c @@ -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))) -{ -} diff --git a/grub-core/kern/mips/loongson/init.c b/grub-core/kern/mips/loongson/init.c index 756439b..1abcf1a 100644 --- a/grub-core/kern/mips/loongson/init.c +++ b/grub-core/kern/mips/loongson/init.c @@ -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; diff --git a/grub-core/kern/mips/qemu_mips/init.c b/grub-core/kern/mips/qemu_mips/init.c index aa414eb..050f19f 100644 --- a/grub-core/kern/mips/qemu_mips/init.c +++ b/grub-core/kern/mips/qemu_mips/init.c @@ -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; diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index cc072c2..f2b24b4 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -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 -- 1.8.2.1