static void prepare_mrc_cache(struct pei_data *pei_data) { struct mrc_data_container *mrc_cache; u16 c1, c2, checksum, seed_checksum; // preset just in case there is an error pei_data->mrc_input = NULL; pei_data->mrc_input_len = 0; /* Read scrambler seeds from CMOS */ pei_data->scrambler_seed = cmos_read32(CMOS_OFFSET_MRC_SEED); printk(BIOS_DEBUG, "Read scrambler seed 0x%08x from CMOS 0x%02x\n", pei_data->scrambler_seed, CMOS_OFFSET_MRC_SEED); pei_data->scrambler_seed_s3 = cmos_read32(CMOS_OFFSET_MRC_SEED_S3); printk(BIOS_DEBUG, "Read S3 scrambler seed 0x%08x from CMOS 0x%02x\n", pei_data->scrambler_seed_s3, CMOS_OFFSET_MRC_SEED_S3); /* Compute seed checksum and compare */ c1 = compute_ip_checksum((u8*)&pei_data->scrambler_seed, sizeof(u32)); c2 = compute_ip_checksum((u8*)&pei_data->scrambler_seed_s3, sizeof(u32)); checksum = add_ip_checksums(sizeof(u32), c1, c2); seed_checksum = cmos_read(CMOS_OFFSET_MRC_SEED_CHK); seed_checksum |= cmos_read(CMOS_OFFSET_MRC_SEED_CHK+1) << 8; if (checksum != seed_checksum) { printk(BIOS_ERR, "%s: invalid seed checksum\n", __func__); pei_data->scrambler_seed = 0; pei_data->scrambler_seed_s3 = 0; return; } if ((mrc_cache = find_current_mrc_cache()) == NULL) { /* error message printed in find_current_mrc_cache */ return; } pei_data->mrc_input = mrc_cache->mrc_data; pei_data->mrc_input_len = mrc_cache->mrc_data_size; printk(BIOS_DEBUG, "%s: at %p, size %x checksum %04x\n", __func__, pei_data->mrc_input, pei_data->mrc_input_len, mrc_cache->mrc_checksum); }
void cmos_post_log(void) { u8 code = 0; #if CONFIG_CMOS_POST_EXTRA u32 extra = 0; #endif spin_lock(&cmos_post_lock); /* Get post code from other bank */ switch (cmos_read(CMOS_POST_BANK_OFFSET)) { case CMOS_POST_BANK_0_MAGIC: code = cmos_read(CMOS_POST_BANK_1_OFFSET); #if CONFIG_CMOS_POST_EXTRA extra = cmos_read32(CMOS_POST_BANK_1_EXTRA); #endif break; case CMOS_POST_BANK_1_MAGIC: code = cmos_read(CMOS_POST_BANK_0_OFFSET); #if CONFIG_CMOS_POST_EXTRA extra = cmos_read32(CMOS_POST_BANK_0_EXTRA); #endif break; } spin_unlock(&cmos_post_lock); /* Check last post code in previous boot against normal list */ switch (code) { case POST_OS_BOOT: case POST_OS_RESUME: case POST_ENTER_ELF_BOOT: case 0: break; default: printk(BIOS_WARNING, "POST: Unexpected post code " "in previous boot: 0x%02x\n", code); #if CONFIG_ELOG elog_add_event_word(ELOG_TYPE_LAST_POST_CODE, code); #if CONFIG_CMOS_POST_EXTRA if (extra) elog_add_event_dword(ELOG_TYPE_POST_EXTRA, extra); #endif #endif } }
int arch_fsp_init(void) { void *nvs; int stack = CONFIG_FSP_TEMP_RAM_ADDR; int boot_mode = BOOT_FULL_CONFIG; #ifdef CONFIG_HAVE_ACPI_RESUME int prev_sleep_state = chipset_prev_sleep_state(); gd->arch.prev_sleep_state = prev_sleep_state; #endif if (!gd->arch.hob_list) { #ifdef CONFIG_ENABLE_MRC_CACHE nvs = fsp_prepare_mrc_cache(); #else nvs = NULL; #endif #ifdef CONFIG_HAVE_ACPI_RESUME if (prev_sleep_state == ACPI_S3) { if (nvs == NULL) { /* If waking from S3 and no cache then */ debug("No MRC cache found in S3 resume path\n"); post_code(POST_RESUME_FAILURE); /* Clear Sleep Type */ chipset_clear_sleep_state(); /* Reboot */ debug("Rebooting..\n"); outb(SYS_RST | RST_CPU, IO_PORT_RESET); /* Should not reach here.. */ panic("Reboot System"); } /* * DM is not avaiable yet at this point, hence call * CMOS access library which does not depend on DM. */ stack = cmos_read32(CMOS_FSP_STACK_ADDR); boot_mode = BOOT_ON_S3_RESUME; } #endif /* * The first time we enter here, call fsp_init(). * Note the execution does not return to this function, * instead it jumps to fsp_continue(). */ fsp_init(stack, boot_mode, nvs); } else { /* * The second time we enter here, adjust the size of malloc() * pool before relocation. Given gd->malloc_base was adjusted * after the call to board_init_f_init_reserve() in arch/x86/ * cpu/start.S, we should fix up gd->malloc_limit here. */ gd->malloc_limit += CONFIG_FSP_SYS_MALLOC_F_LEN; } return 0; }