uboot/arch/x86/lib/spl.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (c) 2016 Google, Inc
   4 */
   5
   6#include <common.h>
   7#include <cpu_func.h>
   8#include <debug_uart.h>
   9#include <dm.h>
  10#include <irq_func.h>
  11#include <malloc.h>
  12#include <spl.h>
  13#include <syscon.h>
  14#include <asm/cpu.h>
  15#include <asm/cpu_common.h>
  16#include <asm/mrccache.h>
  17#include <asm/mtrr.h>
  18#include <asm/pci.h>
  19#include <asm/processor.h>
  20#include <asm/spl.h>
  21#include <asm-generic/sections.h>
  22
  23DECLARE_GLOBAL_DATA_PTR;
  24
  25__weak int arch_cpu_init_dm(void)
  26{
  27        return 0;
  28}
  29
  30#ifdef CONFIG_TPL
  31
  32static int set_max_freq(void)
  33{
  34        if (cpu_get_burst_mode_state() == BURST_MODE_UNAVAILABLE) {
  35                /*
  36                 * Burst Mode has been factory-configured as disabled and is not
  37                 * available in this physical processor package
  38                 */
  39                debug("Burst Mode is factory-disabled\n");
  40                return -ENOENT;
  41        }
  42
  43        /* Enable burst mode */
  44        cpu_set_burst_mode(true);
  45
  46        /* Enable speed step */
  47        cpu_set_eist(true);
  48
  49        /* Set P-State ratio */
  50        cpu_set_p_state_to_turbo_ratio();
  51
  52        return 0;
  53}
  54#endif
  55
  56static int x86_spl_init(void)
  57{
  58#ifndef CONFIG_TPL
  59        /*
  60         * TODO(sjg@chromium.org): We use this area of RAM for the stack
  61         * and global_data in SPL. Once U-Boot starts up and releocates it
  62         * is not needed. We could make this a CONFIG option or perhaps
  63         * place it immediately below CONFIG_SYS_TEXT_BASE.
  64         */
  65        char *ptr = (char *)0x110000;
  66#else
  67        struct udevice *punit;
  68#endif
  69        int ret;
  70
  71        debug("%s starting\n", __func__);
  72        if (IS_ENABLED(TPL))
  73                ret = x86_cpu_reinit_f();
  74        else
  75                ret = x86_cpu_init_f();
  76        ret = spl_init();
  77        if (ret) {
  78                debug("%s: spl_init() failed\n", __func__);
  79                return ret;
  80        }
  81        ret = arch_cpu_init();
  82        if (ret) {
  83                debug("%s: arch_cpu_init() failed\n", __func__);
  84                return ret;
  85        }
  86#ifndef CONFIG_TPL
  87        ret = arch_cpu_init_dm();
  88        if (ret) {
  89                debug("%s: arch_cpu_init_dm() failed\n", __func__);
  90                return ret;
  91        }
  92#endif
  93        preloader_console_init();
  94#ifndef CONFIG_TPL
  95        ret = print_cpuinfo();
  96        if (ret) {
  97                debug("%s: print_cpuinfo() failed\n", __func__);
  98                return ret;
  99        }
 100#endif
 101        ret = dram_init();
 102        if (ret) {
 103                debug("%s: dram_init() failed\n", __func__);
 104                return ret;
 105        }
 106        if (IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)) {
 107                ret = mrccache_spl_save();
 108                if (ret)
 109                        debug("%s: Failed to write to mrccache (err=%d)\n",
 110                              __func__, ret);
 111        }
 112
 113#ifndef CONFIG_TPL
 114        memset(&__bss_start, 0, (ulong)&__bss_end - (ulong)&__bss_start);
 115
 116        /* TODO(sjg@chromium.org): Consider calling cpu_init_r() here */
 117        ret = interrupt_init();
 118        if (ret) {
 119                debug("%s: interrupt_init() failed\n", __func__);
 120                return ret;
 121        }
 122
 123        /*
 124         * The stack grows down from ptr. Put the global data at ptr. This
 125         * will only be used for SPL. Once SPL loads U-Boot proper it will
 126         * set up its own stack.
 127         */
 128        gd->new_gd = (struct global_data *)ptr;
 129        memcpy(gd->new_gd, gd, sizeof(*gd));
 130        arch_setup_gd(gd->new_gd);
 131        gd->start_addr_sp = (ulong)ptr;
 132
 133        /* Cache the SPI flash. Otherwise copying the code to RAM takes ages */
 134        ret = mtrr_add_request(MTRR_TYPE_WRBACK,
 135                               (1ULL << 32) - CONFIG_XIP_ROM_SIZE,
 136                               CONFIG_XIP_ROM_SIZE);
 137        if (ret) {
 138                debug("%s: SPI cache setup failed (err=%d)\n", __func__, ret);
 139                return ret;
 140        }
 141        mtrr_commit(true);
 142#else
 143        ret = syscon_get_by_driver_data(X86_SYSCON_PUNIT, &punit);
 144        if (ret)
 145                debug("Could not find PUNIT (err=%d)\n", ret);
 146
 147        ret = set_max_freq();
 148        if (ret)
 149                debug("Failed to set CPU frequency (err=%d)\n", ret);
 150#endif
 151
 152        return 0;
 153}
 154
 155void board_init_f(ulong flags)
 156{
 157        int ret;
 158
 159        ret = x86_spl_init();
 160        if (ret) {
 161                debug("Error %d\n", ret);
 162                panic("x86_spl_init fail");
 163        }
 164#ifdef CONFIG_TPL
 165        gd->bd = malloc(sizeof(*gd->bd));
 166        if (!gd->bd) {
 167                printf("Out of memory for bd_info size %x\n", sizeof(*gd->bd));
 168                hang();
 169        }
 170        board_init_r(gd, 0);
 171#else
 172        /* Uninit CAR and jump to board_init_f_r() */
 173        board_init_f_r_trampoline(gd->start_addr_sp);
 174#endif
 175}
 176
 177void board_init_f_r(void)
 178{
 179        init_cache_f_r();
 180        gd->flags &= ~GD_FLG_SERIAL_READY;
 181        debug("cache status %d\n", dcache_status());
 182        board_init_r(gd, 0);
 183}
 184
 185u32 spl_boot_device(void)
 186{
 187        return BOOT_DEVICE_SPI_MMAP;
 188}
 189
 190int spl_start_uboot(void)
 191{
 192        return 0;
 193}
 194
 195void spl_board_announce_boot_device(void)
 196{
 197        printf("SPI flash");
 198}
 199
 200static int spl_board_load_image(struct spl_image_info *spl_image,
 201                                struct spl_boot_device *bootdev)
 202{
 203        spl_image->size = CONFIG_SYS_MONITOR_LEN;
 204        spl_image->entry_point = CONFIG_SYS_TEXT_BASE;
 205        spl_image->load_addr = CONFIG_SYS_TEXT_BASE;
 206        spl_image->os = IH_OS_U_BOOT;
 207        spl_image->name = "U-Boot";
 208
 209        debug("Loading to %lx\n", spl_image->load_addr);
 210
 211        return 0;
 212}
 213SPL_LOAD_IMAGE_METHOD("SPI", 5, BOOT_DEVICE_SPI_MMAP, spl_board_load_image);
 214
 215int spl_spi_load_image(void)
 216{
 217        return -EPERM;
 218}
 219
 220#ifdef CONFIG_X86_RUN_64BIT
 221void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
 222{
 223        int ret;
 224
 225        printf("Jumping to 64-bit U-Boot: Note many features are missing\n");
 226        ret = cpu_jump_to_64bit_uboot(spl_image->entry_point);
 227        debug("ret=%d\n", ret);
 228        hang();
 229}
 230#endif
 231
 232void spl_board_init(void)
 233{
 234#ifndef CONFIG_TPL
 235        preloader_console_init();
 236#endif
 237}
 238