Home | History | Annotate | Download | only in lib
      1 // SPDX-License-Identifier: GPL-2.0
      2 /*
      3  * Copyright (c) 2016 Google, Inc
      4  */
      5 
      6 #include <common.h>
      7 #include <debug_uart.h>
      8 #include <spl.h>
      9 #include <asm/cpu.h>
     10 #include <asm/mtrr.h>
     11 #include <asm/processor.h>
     12 #include <asm-generic/sections.h>
     13 
     14 DECLARE_GLOBAL_DATA_PTR;
     15 
     16 __weak int arch_cpu_init_dm(void)
     17 {
     18 	return 0;
     19 }
     20 
     21 static int x86_spl_init(void)
     22 {
     23 	/*
     24 	 * TODO(sjg (at) chromium.org): We use this area of RAM for the stack
     25 	 * and global_data in SPL. Once U-Boot starts up and releocates it
     26 	 * is not needed. We could make this a CONFIG option or perhaps
     27 	 * place it immediately below CONFIG_SYS_TEXT_BASE.
     28 	 */
     29 	char *ptr = (char *)0x110000;
     30 	int ret;
     31 
     32 	debug("%s starting\n", __func__);
     33 	ret = spl_init();
     34 	if (ret) {
     35 		debug("%s: spl_init() failed\n", __func__);
     36 		return ret;
     37 	}
     38 	ret = arch_cpu_init();
     39 	if (ret) {
     40 		debug("%s: arch_cpu_init() failed\n", __func__);
     41 		return ret;
     42 	}
     43 	ret = arch_cpu_init_dm();
     44 	if (ret) {
     45 		debug("%s: arch_cpu_init_dm() failed\n", __func__);
     46 		return ret;
     47 	}
     48 	preloader_console_init();
     49 	ret = print_cpuinfo();
     50 	if (ret) {
     51 		debug("%s: print_cpuinfo() failed\n", __func__);
     52 		return ret;
     53 	}
     54 	ret = dram_init();
     55 	if (ret) {
     56 		debug("%s: dram_init() failed\n", __func__);
     57 		return ret;
     58 	}
     59 	memset(&__bss_start, 0, (ulong)&__bss_end - (ulong)&__bss_start);
     60 
     61 	/* TODO(sjg (at) chromium.org): Consider calling cpu_init_r() here */
     62 	ret = interrupt_init();
     63 	if (ret) {
     64 		debug("%s: interrupt_init() failed\n", __func__);
     65 		return ret;
     66 	}
     67 
     68 	/*
     69 	 * The stack grows down from ptr. Put the global data at ptr. This
     70 	 * will only be used for SPL. Once SPL loads U-Boot proper it will
     71 	 * set up its own stack.
     72 	 */
     73 	gd->new_gd = (struct global_data *)ptr;
     74 	memcpy(gd->new_gd, gd, sizeof(*gd));
     75 	arch_setup_gd(gd->new_gd);
     76 	gd->start_addr_sp = (ulong)ptr;
     77 
     78 	/* Cache the SPI flash. Otherwise copying the code to RAM takes ages */
     79 	ret = mtrr_add_request(MTRR_TYPE_WRBACK,
     80 			       (1ULL << 32) - CONFIG_XIP_ROM_SIZE,
     81 			       CONFIG_XIP_ROM_SIZE);
     82 	if (ret) {
     83 		debug("%s: SPI cache setup failed\n", __func__);
     84 		return ret;
     85 	}
     86 
     87 	return 0;
     88 }
     89 
     90 void board_init_f(ulong flags)
     91 {
     92 	int ret;
     93 
     94 	ret = x86_spl_init();
     95 	if (ret) {
     96 		debug("Error %d\n", ret);
     97 		hang();
     98 	}
     99 
    100 	/* Uninit CAR and jump to board_init_f_r() */
    101 	board_init_f_r_trampoline(gd->start_addr_sp);
    102 }
    103 
    104 void board_init_f_r(void)
    105 {
    106 	init_cache_f_r();
    107 	gd->flags &= ~GD_FLG_SERIAL_READY;
    108 	debug("cache status %d\n", dcache_status());
    109 	board_init_r(gd, 0);
    110 }
    111 
    112 u32 spl_boot_device(void)
    113 {
    114 	return BOOT_DEVICE_BOARD;
    115 }
    116 
    117 int spl_start_uboot(void)
    118 {
    119 	return 0;
    120 }
    121 
    122 void spl_board_announce_boot_device(void)
    123 {
    124 	printf("SPI flash");
    125 }
    126 
    127 static int spl_board_load_image(struct spl_image_info *spl_image,
    128 				struct spl_boot_device *bootdev)
    129 {
    130 	spl_image->size = CONFIG_SYS_MONITOR_LEN;
    131 	spl_image->entry_point = CONFIG_SYS_TEXT_BASE;
    132 	spl_image->load_addr = CONFIG_SYS_TEXT_BASE;
    133 	spl_image->os = IH_OS_U_BOOT;
    134 	spl_image->name = "U-Boot";
    135 
    136 	debug("Loading to %lx\n", spl_image->load_addr);
    137 
    138 	return 0;
    139 }
    140 SPL_LOAD_IMAGE_METHOD("SPI", 0, BOOT_DEVICE_BOARD, spl_board_load_image);
    141 
    142 int spl_spi_load_image(void)
    143 {
    144 	return -EPERM;
    145 }
    146 
    147 void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
    148 {
    149 	int ret;
    150 
    151 	printf("Jumping to 64-bit U-Boot: Note many features are missing\n");
    152 	ret = cpu_jump_to_64bit_uboot(spl_image->entry_point);
    153 	debug("ret=%d\n", ret);
    154 	while (1)
    155 		;
    156 }
    157