Mercurial > nand-ecoscentric
changeset 1742:aaa68fc7d7f9
Add -x option to ARM RedBoot exec command
| author | msalter |
|---|---|
| date | Thu, 02 Sep 2004 16:30:51 +0000 |
| parents | 3480e423c3a2 |
| children | 6a8c35811e3d |
| files | packages/hal/arm/arch/current/ChangeLog packages/hal/arm/arch/current/cdl/hal_arm.cdl packages/hal/arm/arch/current/src/redboot_linux_exec.c |
| diffstat | 3 files changed, 108 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/packages/hal/arm/arch/current/ChangeLog +++ b/packages/hal/arm/arch/current/ChangeLog @@ -1,3 +1,11 @@ +2004-09-02 Mark Salter <msalter@redhat.com> + + * cdl/hal_arm.cdl (CYGHWR_REDBOOT_LINUX_EXEC_X_SWITCH): New + option used to enable "-x" option to exec command. + + * src/redboot_linux_exec.c (do_exec): Add support for booting + kernels built for endianess oppposite of RedBoot. + 2004-07-07 Gary Thomas <gary@mlbassoc.com> * src/redboot_linux_exec.c (do_exec): Fix test for valid entry
--- a/packages/hal/arm/arch/current/cdl/hal_arm.cdl +++ b/packages/hal/arm/arch/current/cdl/hal_arm.cdl @@ -249,6 +249,15 @@ cdl_package CYGPKG_HAL_ARM { RedBoots CDL." compile -library=libextras.a redboot_linux_exec.c + cdl_option CYGHWR_REDBOOT_LINUX_EXEC_X_SWITCH { + display "Enable -x switch for exec command." + flavor bool + default_value 0 + description " + This option allows bi-endian platforms to launch kernels + built for an endianess different than the RedBoot endianess" + } + cdl_option CYGHWR_REDBOOT_ARM_LINUX_EXEC_ADDRESS { display "Physical base address of linux kernel" flavor data
--- a/packages/hal/arm/arch/current/src/redboot_linux_exec.c +++ b/packages/hal/arm/arch/current/src/redboot_linux_exec.c @@ -8,7 +8,7 @@ //####ECOSGPLCOPYRIGHTBEGIN#### // ------------------------------------------- // This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc. +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc. // Copyright (C) 2003, 2004 Gary Thomas // // eCos is free software; you can redistribute it and/or modify it under @@ -100,15 +100,44 @@ RedBoot_cmd("exec", // address. Some ARM implementations may need special handling and define // their own version. #ifndef CYGARC_HAL_MMU_OFF -#define CYGARC_HAL_MMU_OFF(__paddr__) \ - " mcr p15,0,r0,c7,c10,4\n" \ - " mcr p15,0,r0,c7,c7,0\n" \ - " mrc p15,0,r0,c1,c0,0\n" \ + +#define __CYGARC_GET_CTLREG \ + " mrc p15,0,r0,c1,c0,0\n" + +#define __CYGARC_CLR_MMU_BITS \ + " bic r0,r0,#0xd\n" \ + " bic r0,r0,#0x1000\n" \ + +#ifdef CYGHWR_HAL_ARM_BIGENDIAN +#define __CYGARC_CLR_MMU_BITS_X \ + " bic r0,r0,#0x8d\n" \ + " bic r0,r0,#0x1000\n" +#else +#define __CYGARC_CLR_MMU_BITS_X \ " bic r0,r0,#0xd\n" \ " bic r0,r0,#0x1000\n" \ - " mcr p15,0,r0,c1,c0,0\n" \ + " orr r0,r0,#0x80\n" +#endif + +#define __CYGARC_SET_CTLREG(__paddr__) \ + " mcr p15,0,r0,c1,c0,0\n" \ " mov pc," #__paddr__ "\n" -#endif + +#define CYGARC_HAL_MMU_OFF(__paddr__) \ + " mcr p15,0,r0,c7,c10,4\n" \ + " mcr p15,0,r0,c7,c7,0\n" \ + __CYGARC_GET_CTLREG \ + __CYGARC_CLR_MMU_BITS \ + __CYGARC_SET_CTLREG(__paddr__) + +#define CYGARC_HAL_MMU_OFF_X(__paddr__) \ + " mcr p15,0,r0,c7,c10,4\n" \ + " mcr p15,0,r0,c7,c7,0\n" \ + __CYGARC_GET_CTLREG \ + __CYGARC_CLR_MMU_BITS_X \ + __CYGARC_SET_CTLREG(__paddr__) + +#endif // CYGARC_HAL_MMU_OFF // // Parameter info for Linux kernel @@ -280,15 +309,19 @@ do_exec(int argc, char *argv[]) unsigned long entry; unsigned long oldints; bool wait_time_set; - int wait_time, res; + int wait_time, res, num_opts; bool base_addr_set, length_set, cmd_line_set; bool ramdisk_addr_set, ramdisk_size_set; unsigned long base_addr, length; unsigned long ramdisk_addr, ramdisk_size; - struct option_info opts[6]; + struct option_info opts[7]; char line[8]; char *cmd_line; struct tag *params = (struct tag *)CYGHWR_REDBOOT_ARM_LINUX_TAGS_ADDRESS; +#ifdef CYGHWR_REDBOOT_LINUX_EXEC_X_SWITCH + bool swap_endian; + extern char __xtramp_start__[], __xtramp_end__[]; +#endif extern char __tramp_start__[], __tramp_end__[]; // Check to see if a valid image has been loaded @@ -317,7 +350,13 @@ do_exec(int argc, char *argv[]) (void **)&ramdisk_addr, (bool *)&ramdisk_addr_set, "ramdisk_addr"); init_opts(&opts[5], 's', true, OPTION_ARG_TYPE_NUM, (void **)&ramdisk_size, (bool *)&ramdisk_size_set, "ramdisk_size"); - if (!scan_opts(argc, argv, 1, opts, 6, (void *)&entry, OPTION_ARG_TYPE_NUM, "[physical] starting address")) + num_opts = 6; +#ifdef CYGHWR_REDBOOT_LINUX_EXEC_X_SWITCH + init_opts(&opts[6], 'x', false, OPTION_ARG_TYPE_FLG, + (void **)&swap_endian, 0, "swap endianess"); + ++num_opts; +#endif + if (!scan_opts(argc, argv, 1, opts, num_opts, (void *)&entry, OPTION_ARG_TYPE_NUM, "[physical] starting address")) { return; } @@ -405,6 +444,48 @@ do_exec(int argc, char *argv[]) // This magic was created in order to be able to execute standard // Linux kernels with as little change/perturberance as possible. +#ifdef CYGHWR_REDBOOT_LINUX_EXEC_X_SWITCH + if (swap_endian) { + // copy the trampline code + memcpy((char *)CYGHWR_REDBOOT_ARM_TRAMPOLINE_ADDRESS, + __xtramp_start__, + __xtramp_end__ - __xtramp_start__); + + asm volatile ( + CYGARC_HAL_MMU_OFF_X(%5) + "__xtramp_start__:\n" + " cmp %1,%4;\n" // Default kernel load address. Relocate + " beq 2f;\n" // kernel image there if necessary, and + " cmp %2,#0;\n" // if size is non-zero + " beq 2f;\n" + "1:\n" + " ldr r0,[%1],#4;\n" + " eor %5, r0, r0, ror #16;\n" + " bic %5, %5, #0x00ff0000;\n" + " mov r0, r0, ror #8;\n" + " eor r0, r0, %5, lsr #8;\n" + " str r0,[%4],#4;\n" + " subs %2,%2,#4;\n" + " bne 1b;\n" + "2:\n" + " mov r0,#0;\n" // Set board type + " mov r1,%3;\n" // Machine type + " mov r2,%6;\n" // Kernel parameters + " mov pc,%0;\n" // Jump to kernel + "__xtramp_end__:\n" + : : + "r"(entry), + "r"(CYGARC_PHYSICAL_ADDRESS(base_addr)), + "r"(length), + "r"(CYGHWR_REDBOOT_ARM_MACHINE_TYPE), + "r"(CYGHWR_REDBOOT_ARM_LINUX_EXEC_ADDRESS), + "r"(CYGARC_PHYSICAL_ADDRESS(CYGHWR_REDBOOT_ARM_TRAMPOLINE_ADDRESS)), + "r"(CYGARC_PHYSICAL_ADDRESS(CYGHWR_REDBOOT_ARM_LINUX_TAGS_ADDRESS)) + : "r0", "r1" + ); + } +#endif // CYGHWR_REDBOOT_LINUX_EXEC_X_SWITCH + // copy the trampline code memcpy((char *)CYGHWR_REDBOOT_ARM_TRAMPOLINE_ADDRESS, __tramp_start__,
