Exemple #1
0
/**
 * Find PEI executable in coreboot filesystem and execute it.
 *
 * @param pei_data: configuration data for UEFI PEI reference code
 */
void sdram_initialize(struct pei_data *pei_data)
{
	struct sys_info sysinfo;
	int (*entry) (struct pei_data *pei_data) __attribute__ ((regparm(1)));

	report_platform_info();

	/* Wait for ME to be ready */
	intel_early_me_init();
	intel_early_me_uma_size();

	printk(BIOS_DEBUG, "Starting UEFI PEI System Agent\n");

	memset(&sysinfo, 0, sizeof(sysinfo));

	sysinfo.boot_path = pei_data->boot_mode;

	/*
	 * Do not pass MRC data in for recovery mode boot,
	 * Always pass it in for S3 resume.
	 */
	if (!recovery_mode_enabled() || pei_data->boot_mode == 2)
		prepare_mrc_cache(pei_data);

	/* If MRC data is not found we cannot continue S3 resume. */
	if (pei_data->boot_mode == 2 && !pei_data->mrc_input) {
		printk(BIOS_DEBUG, "Giving up in sdram_initialize: No MRC data\n");
		outb(0x6, 0xcf9);
		halt();
	}

	/* Pass console handler in pei_data */
	pei_data->tx_byte = do_putchar;

	/* Locate and call UEFI System Agent binary. */
	entry = cbfs_get_file_content(
		CBFS_DEFAULT_MEDIA, "mrc.bin", CBFS_TYPE_MRC, NULL);
	if (entry) {
		int rv;
		rv = entry (pei_data);
		if (rv) {
			switch (rv) {
			case -1:
				printk(BIOS_ERR, "PEI version mismatch.\n");
				break;
			case -2:
				printk(BIOS_ERR, "Invalid memory frequency.\n");
				break;
			default:
				printk(BIOS_ERR, "MRC returned %x.\n", rv);
			}
			die("Nonzero MRC return value.\n");
		}
	} else {
		die("UEFI PEI System Agent not found.\n");
	}

#if CONFIG_USBDEBUG_IN_ROMSTAGE
	/* mrc.bin reconfigures USB, so reinit it to have debug */
	usbdebug_init();
#endif

	/* For reference print the System Agent version
	 * after executing the UEFI PEI stage.
	 */
	u32 version = MCHBAR32(0x5034);
	printk(BIOS_DEBUG, "System Agent Version %d.%d.%d Build %d\n",
		version >> 24 , (version >> 16) & 0xff,
		(version >> 8) & 0xff, version & 0xff);

	/* Send ME init done for SandyBridge here.  This is done
	 * inside the SystemAgent binary on IvyBridge. */
	if (BASE_REV_SNB ==
	    (pci_read_config16(PCI_CPU_DEVICE, PCI_DEVICE_ID) & BASE_REV_MASK))
		intel_early_me_init_done(ME_INIT_STATUS_SUCCESS);
	else
		intel_early_me_status();

	post_system_agent_init(pei_data);
	report_memory_config();
}
Exemple #2
0
/**
 * Find the PEI executable in the ROM and execute it.
 *
 * @param pei_data: configuration data for UEFI PEI reference code
 */
int sdram_initialise(struct pei_data *pei_data)
{
    unsigned version;
    const char *data;
    uint16_t done;
    int ret;

    report_platform_info();

    /* Wait for ME to be ready */
    ret = intel_early_me_init();
    if (ret)
        return ret;
    ret = intel_early_me_uma_size();
    if (ret < 0)
        return ret;

    debug("Starting UEFI PEI System Agent\n");

    /*
     * Do not pass MRC data in for recovery mode boot,
     * Always pass it in for S3 resume.
     */
    if (!recovery_mode_enabled() ||
            pei_data->boot_mode == PEI_BOOT_RESUME) {
        ret = prepare_mrc_cache(pei_data);
        if (ret)
            debug("prepare_mrc_cache failed: %d\n", ret);
    }

    /* If MRC data is not found we cannot continue S3 resume. */
    if (pei_data->boot_mode == PEI_BOOT_RESUME && !pei_data->mrc_input) {
        debug("Giving up in sdram_initialize: No MRC data\n");
        reset_cpu(0);
    }

    /* Pass console handler in pei_data */
    pei_data->tx_byte = console_tx_byte;

    debug("PEI data at %p, size %x:\n", pei_data, sizeof(*pei_data));

    data = (char *)CONFIG_X86_MRC_ADDR;
    if (data) {
        int rv;
        int (*func)(struct pei_data *);

        debug("Calling MRC at %p\n", data);
        post_code(POST_PRE_MRC);
        func = (int (*)(struct pei_data *))data;
        rv = func(pei_data);
        post_code(POST_MRC);
        if (rv) {
            switch (rv) {
            case -1:
                printf("PEI version mismatch.\n");
                break;
            case -2:
                printf("Invalid memory frequency.\n");
                break;
            default:
                printf("MRC returned %x.\n", rv);
            }
            printf("Nonzero MRC return value.\n");
            return -EFAULT;
        }
    } else {
        printf("UEFI PEI System Agent not found.\n");
        return -ENOSYS;
    }

#if CONFIG_USBDEBUG
    /* mrc.bin reconfigures USB, so reinit it to have debug */
    early_usbdebug_init();
#endif

    version = readl(MCHBAR_REG(0x5034));
    debug("System Agent Version %d.%d.%d Build %d\n",
          version >> 24 , (version >> 16) & 0xff,
          (version >> 8) & 0xff, version & 0xff);
    debug("MCR output data length %#x at %p\n", pei_data->mrc_output_len,
          pei_data->mrc_output);

    /*
     * Send ME init done for SandyBridge here.  This is done inside the
     * SystemAgent binary on IvyBridge
     */
    done = x86_pci_read_config32(PCH_DEV, PCI_DEVICE_ID);
    done &= BASE_REV_MASK;
    if (BASE_REV_SNB == done)
        intel_early_me_init_done(ME_INIT_STATUS_SUCCESS);
    else
        intel_early_me_status();

    post_system_agent_init(pei_data);
    report_memory_config();

    /* S3 resume: don't save scrambler seed or MRC data */
    if (pei_data->boot_mode != PEI_BOOT_RESUME) {
        /*
         * This will be copied to SDRAM in reserve_arch(), then written
         * to SPI flash in sdram_save_mrc_data()
         */
        gd->arch.mrc_output = (char *)pei_data->mrc_output;
        gd->arch.mrc_output_len = pei_data->mrc_output_len;
        ret = write_seeds_to_cmos(pei_data);
        if (ret)
            debug("Failed to write seeds to CMOS: %d\n", ret);
    }

    return 0;
}