return 0;
}
+__weak int board_prep_linux(bootm_headers_t *images) { return 0; }
+
/* Subcommand: PREP */
-static void boot_prep_linux(bootm_headers_t *images)
+static int boot_prep_linux(bootm_headers_t *images)
{
- if (image_setup_linux(images))
- hang();
+ int ret;
+
+ ret = image_setup_linux(images);
+ if (ret)
+ return ret;
+
+ return board_prep_linux(images);
}
-__weak void smp_set_core_boot_addr(unsigned long addr, int corenr) {}
-__weak void smp_kick_all_cpus(void) {}
+/* Generic implementation for single core CPU */
+__weak void board_jump_and_run(ulong entry, int zero, int arch, uint params)
+{
+ void (*kernel_entry)(int zero, int arch, uint params);
+
+ kernel_entry = (void (*)(int, int, uint))entry;
+
+ kernel_entry(zero, arch, params);
+}
/* Subcommand: GO */
static void boot_jump_linux(bootm_headers_t *images, int flag)
{
- void (*kernel_entry)(int zero, int arch, uint params);
+ ulong kernel_entry;
unsigned int r0, r2;
int fake = (flag & BOOTM_STATE_OS_FAKE_GO);
- kernel_entry = (void (*)(int, int, uint))images->ep;
+ kernel_entry = images->ep;
debug("## Transferring control to Linux (at address %08lx)...\n",
- (ulong) kernel_entry);
+ kernel_entry);
bootstage_mark(BOOTSTAGE_ID_RUN_OS);
printf("\nStarting kernel ...%s\n\n", fake ?
"(fake run for tracing)" : "");
bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel");
- cleanup_before_linux();
-
if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) {
r0 = 2;
r2 = (unsigned int)images->ft_addr;
r2 = (unsigned int)env_get("bootargs");
}
- if (!fake) {
- smp_set_core_boot_addr((unsigned long)kernel_entry, -1);
- smp_kick_all_cpus();
- kernel_entry(r0, 0, r2);
- }
+ cleanup_before_linux();
+
+ if (!fake)
+ board_jump_and_run(kernel_entry, r0, 0, r2);
}
int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
if ((flag & BOOTM_STATE_OS_BD_T) || (flag & BOOTM_STATE_OS_CMDLINE))
return -1;
- if (flag & BOOTM_STATE_OS_PREP) {
- boot_prep_linux(images);
- return 0;
- }
+ if (flag & BOOTM_STATE_OS_PREP)
+ return boot_prep_linux(images);
if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) {
boot_jump_linux(images, flag);
return 0;
}
- boot_prep_linux(images);
- boot_jump_linux(images, flag);
- return 0;
+ return -1;
}
}
#ifdef CONFIG_ISA_ARCV2
+
+void board_jump_and_run(ulong entry, int zero, int arch, uint params)
+{
+ void (*kernel_entry)(int zero, int arch, uint params);
+
+ kernel_entry = (void (*)(int, int, uint))entry;
+
+ smp_set_core_boot_addr(entry, -1);
+ smp_kick_all_cpus();
+ kernel_entry(zero, arch, params);
+}
+
#define RESET_VECTOR_ADDR 0x0
void smp_set_core_boot_addr(unsigned long addr, int corenr)
return 0;
}
+void board_jump_and_run(ulong entry, int zero, int arch, uint params)
+{
+ void (*kernel_entry)(int zero, int arch, uint params);
+
+ kernel_entry = (void (*)(int, int, uint))entry;
+
+ smp_set_core_boot_addr(entry, -1);
+ smp_kick_all_cpus();
+ kernel_entry(zero, arch, params);
+}
+
#define RESET_VECTOR_ADDR 0x0
void smp_set_core_boot_addr(unsigned long addr, int corenr)