1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> 4 */ 5 6 #include <common.h> 7 #include <dm.h> 8 #include <errno.h> 9 #include <rtc.h> 10 #include <asm/acpi_s3.h> 11 #include <asm/cmos_layout.h> 12 #include <asm/early_cmos.h> 13 #include <asm/io.h> 14 #include <asm/mrccache.h> 15 #include <asm/post.h> 16 #include <asm/processor.h> 17 #include <asm/fsp/fsp_support.h> 18 19 DECLARE_GLOBAL_DATA_PTR; 20 21 int checkcpu(void) 22 { 23 return 0; 24 } 25 26 int print_cpuinfo(void) 27 { 28 post_code(POST_CPU_INFO); 29 return default_print_cpuinfo(); 30 } 31 32 int fsp_init_phase_pci(void) 33 { 34 u32 status; 35 36 /* call into FspNotify */ 37 debug("Calling into FSP (notify phase INIT_PHASE_PCI): "); 38 status = fsp_notify(NULL, INIT_PHASE_PCI); 39 if (status) 40 debug("fail, error code %x\n", status); 41 else 42 debug("OK\n"); 43 44 return status ? -EPERM : 0; 45 } 46 47 void board_final_cleanup(void) 48 { 49 u32 status; 50 51 /* call into FspNotify */ 52 debug("Calling into FSP (notify phase INIT_PHASE_BOOT): "); 53 status = fsp_notify(NULL, INIT_PHASE_BOOT); 54 if (status) 55 debug("fail, error code %x\n", status); 56 else 57 debug("OK\n"); 58 59 return; 60 } 61 62 static __maybe_unused void *fsp_prepare_mrc_cache(void) 63 { 64 struct mrc_data_container *cache; 65 struct mrc_region entry; 66 int ret; 67 68 ret = mrccache_get_region(NULL, &entry); 69 if (ret) 70 return NULL; 71 72 cache = mrccache_find_current(&entry); 73 if (!cache) 74 return NULL; 75 76 debug("%s: mrc cache at %p, size %x checksum %04x\n", __func__, 77 cache->data, cache->data_size, cache->checksum); 78 79 return cache->data; 80 } 81 82 #ifdef CONFIG_HAVE_ACPI_RESUME 83 int fsp_save_s3_stack(void) 84 { 85 struct udevice *dev; 86 int ret; 87 88 if (gd->arch.prev_sleep_state == ACPI_S3) 89 return 0; 90 91 ret = uclass_get_device(UCLASS_RTC, 0, &dev); 92 if (ret) { 93 debug("Cannot find RTC: err=%d\n", ret); 94 return -ENODEV; 95 } 96 97 /* Save the stack address to CMOS */ 98 ret = rtc_write32(dev, CMOS_FSP_STACK_ADDR, gd->start_addr_sp); 99 if (ret) { 100 debug("Save stack address to CMOS: err=%d\n", ret); 101 return -EIO; 102 } 103 104 return 0; 105 } 106 #endif 107 108 int arch_fsp_init(void) 109 { 110 void *nvs; 111 int stack = CONFIG_FSP_TEMP_RAM_ADDR; 112 int boot_mode = BOOT_FULL_CONFIG; 113 #ifdef CONFIG_HAVE_ACPI_RESUME 114 int prev_sleep_state = chipset_prev_sleep_state(); 115 gd->arch.prev_sleep_state = prev_sleep_state; 116 #endif 117 118 if (!gd->arch.hob_list) { 119 #ifdef CONFIG_ENABLE_MRC_CACHE 120 nvs = fsp_prepare_mrc_cache(); 121 #else 122 nvs = NULL; 123 #endif 124 125 #ifdef CONFIG_HAVE_ACPI_RESUME 126 if (prev_sleep_state == ACPI_S3) { 127 if (nvs == NULL) { 128 /* If waking from S3 and no cache then */ 129 debug("No MRC cache found in S3 resume path\n"); 130 post_code(POST_RESUME_FAILURE); 131 /* Clear Sleep Type */ 132 chipset_clear_sleep_state(); 133 /* Reboot */ 134 debug("Rebooting..\n"); 135 outb(SYS_RST | RST_CPU, IO_PORT_RESET); 136 /* Should not reach here.. */ 137 panic("Reboot System"); 138 } 139 140 /* 141 * DM is not avaiable yet at this point, hence call 142 * CMOS access library which does not depend on DM. 143 */ 144 stack = cmos_read32(CMOS_FSP_STACK_ADDR); 145 boot_mode = BOOT_ON_S3_RESUME; 146 } 147 #endif 148 /* 149 * The first time we enter here, call fsp_init(). 150 * Note the execution does not return to this function, 151 * instead it jumps to fsp_continue(). 152 */ 153 fsp_init(stack, boot_mode, nvs); 154 } else { 155 /* 156 * The second time we enter here, adjust the size of malloc() 157 * pool before relocation. Given gd->malloc_base was adjusted 158 * after the call to board_init_f_init_reserve() in arch/x86/ 159 * cpu/start.S, we should fix up gd->malloc_limit here. 160 */ 161 gd->malloc_limit += CONFIG_FSP_SYS_MALLOC_F_LEN; 162 } 163 164 return 0; 165 } 166