1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2011 Andes Technology Corporation 4 * Shawn Lin, Andes Technology Corporation <nobuhiro@andestech.com> 5 * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com> 6 * Rick Chen, Andes Technology Corporation <rick@andestech.com> 7 */ 8 9 #include <common.h> 10 #include <command.h> 11 #include <image.h> 12 #include <asm/byteorder.h> 13 #include <asm/csr.h> 14 #include <dm/device.h> 15 #include <dm/root.h> 16 #include <u-boot/zlib.h> 17 18 DECLARE_GLOBAL_DATA_PTR; 19 20 __weak void board_quiesce_devices(void) 21 { 22 } 23 24 int arch_fixup_fdt(void *blob) 25 { 26 return 0; 27 } 28 29 int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) 30 { 31 void (*kernel)(ulong hart, void *dtb); 32 33 /* 34 * allow the PREP bootm subcommand, it is required for bootm to work 35 */ 36 if (flag & BOOTM_STATE_OS_PREP) 37 return 0; 38 39 if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) 40 return 1; 41 42 kernel = (void (*)(ulong, void *))images->ep; 43 44 bootstage_mark(BOOTSTAGE_ID_RUN_OS); 45 46 debug("## Transferring control to Linux (at address %08lx) ...\n", 47 (ulong)kernel); 48 49 if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) { 50 #ifdef CONFIG_OF_LIBFDT 51 debug("using: FDT\n"); 52 if (image_setup_linux(images)) { 53 printf("FDT creation failed! hanging..."); 54 hang(); 55 } 56 #endif 57 } 58 59 /* we assume that the kernel is in place */ 60 printf("\nStarting kernel ...\n\n"); 61 62 /* 63 * Call remove function of all devices with a removal flag set. 64 * This may be useful for last-stage operations, like cancelling 65 * of DMA operation or releasing device internal buffers. 66 */ 67 dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL); 68 69 cleanup_before_linux(); 70 71 if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) 72 kernel(csr_read(mhartid), images->ft_addr); 73 74 /* does not return */ 75 76 return 1; 77 } 78