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