/**
 * Update the UPD data based on values from devicetree.cb
 *
 * @param UpdData Pointer to the UPD Data structure
 */
static void ConfigureDefaultUpdData(UPD_DATA_REGION *UpdData)
{
	/*
	 * Serial Port
	 */
	if (IS_ENABLED(CONFIG_INTEGRATED_UART))
		UpdData->SerialPortConfigure = 1;

	/*
	 * Memory Down
	 */
	if (IS_ENABLED(CONFIG_FSP_MEMORY_DOWN)) {
		UpdData->MemDownEnable = 1;

		if (IS_ENABLED(CONFIG_FSP_MEMORY_DOWN_CH0DIMM0_SPD_PRESENT))
			UpdData->MemDownCh0Dimm0SpdPtr
			= (UINT32)cbfs_boot_map_with_leak("spd_ch0_dimm0.bin", CBFS_TYPE_RAW, NULL);
		if (IS_ENABLED(CONFIG_FSP_MEMORY_DOWN_CH0DIMM1_SPD_PRESENT))
			UpdData->MemDownCh0Dimm1SpdPtr
			= (UINT32)cbfs_boot_map_with_leak("spd_ch0_dimm1.bin", CBFS_TYPE_RAW, NULL);
		if (IS_ENABLED(CONFIG_FSP_MEMORY_DOWN_CH1DIMM0_SPD_PRESENT))
			UpdData->MemDownCh1Dimm0SpdPtr
			= (UINT32)cbfs_boot_map_with_leak("spd_ch1_dimm0.bin", CBFS_TYPE_RAW, NULL);
		if (IS_ENABLED(CONFIG_FSP_MEMORY_DOWN_CH1DIMM1_SPD_PRESENT))
			UpdData->MemDownCh1Dimm1SpdPtr
			= (UINT32)cbfs_boot_map_with_leak("spd_ch1_dimm1.bin", CBFS_TYPE_RAW, NULL);
	} else {
		UpdData->MemDownEnable = 0;
	}
	printk(FSP_INFO_LEVEL, "Memory Down Support: %s\n",
		UpdData->MemDownEnable ? "Enabled" : "Disabled");

	/*
	 * Fast Boot
	 */
	if (IS_ENABLED(CONFIG_ENABLE_MRC_CACHE))
		UpdData->MemFastBoot = 1;
	else
		UpdData->MemFastBoot = 0;

	/*
	 * Hyper-Threading
	 */
	if (IS_ENABLED(CONFIG_FSP_HYPERTHREADING))
		UpdData->HyperThreading = 1;
	else
		UpdData->HyperThreading = 0;
}
Esempio n. 2
0
static uint8_t retrieve_board_id(void)
{
	const char *board_id_file_name = CBFS_BOARD_ID_FILE_NAME;
	char *file_contents;
	int i;
	size_t length;

	file_contents = cbfs_boot_map_with_leak(board_id_file_name,
						CBFS_TYPE_RAW, &length);

	if (!file_contents) {
		printk(BIOS_WARNING,
		       "board_id: failed to locate file '%s'\n",
		       board_id_file_name);
		return 0;
	}

	for (i = 0; i < ARRAY_SIZE(board_id_map); i++) {
		const struct bid_map *entry = board_id_map + i;

		if ((strlen(entry->board_name) == length) &&
		    !strncmp(entry->board_name, file_contents, length)) {
			printk(BIOS_INFO, "board_id: name '%s', ID %d\n",
			       entry->board_name, entry->board_id);
			return entry->board_id;
		}
	}

	printk(BIOS_WARNING, "board_id: no match for board name '%.*s'\n",
	       length, file_contents);
	printk(BIOS_WARNING, "board_id: will use default board ID 0\n");

	return 0;
}
Esempio n. 3
0
/* Get SPD data for on-board memory */
uint8_t *mainboard_find_spd_data()
{
	uint8_t *spd_data;
	int spd_index;
	size_t spd_file_len;
	char *spd_file;

	spd_index = 0;

	spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD,
					   &spd_file_len);
	if (!spd_file)
		die("SPD data not found.");

	if (spd_file_len < ((spd_index + 1) * SPD_LEN)) {
		printk(BIOS_ERR,
		       "SPD index override to 0 due to incorrect SPD index.\n");
		spd_index = 0;
	}

	if (spd_file_len < SPD_LEN)
		die("Missing SPD data.");

	/* Assume same memory in both channels */
	spd_index *= SPD_LEN;
	spd_data = (uint8_t *)(spd_file + spd_index);

	/* Make sure a valid SPD was found */
	if (spd_data[0] == 0)
		die("Invalid SPD data.");

	return spd_data;
}
Esempio n. 4
0
void mainboard_romstage_entry(struct romstage_params *rp)
{
	void *spd_content;
	int dual_channel = 0;
	void *spd_file;
	size_t spd_fsize;

	struct mrc_params mp = {
		.mainboard = {
			.dram_type = DRAM_DDR3L,
			.dram_info_location = DRAM_INFO_SPD_MEM,
			.weaker_odt_settings = 1,
		},
	};

	spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD,
						&spd_fsize);
	if (!spd_file)
		die("SPD data not found.");

	/* Both channels are always present. */
	spd_content = get_spd_pointer(spd_file, spd_fsize / SPD_SIZE,
	                              &dual_channel);
	mp.mainboard.dram_data[0] = spd_content;
	if (dual_channel)
		mp.mainboard.dram_data[1] = spd_content;

	rp->mrc_params = &mp;
	romstage_common(rp);
}
Esempio n. 5
0
unsigned long mainboard_write_acpi_tables(device_t dev, unsigned long start, acpi_rsdp_t *rsdp)
{
	unsigned long current;
	acpi_header_t *ssdtx;
	const void *p;
	size_t p_size;

	int i;

	get_bus_conf(); /* it will get sblk, pci1234, hcdn, and sbdn */

	/* Align ACPI tables to 16 bytes */
	start = ALIGN(start, 16);
	current = start;

	/* same htio, but different position? We may have to copy, change HCIN, and recalculate the checknum and add_table */

	for(i = 1; i < sysconf.hc_possible_num; i++) {  /*  0: is hc sblink */
		const char *file_name;
		if((sysconf.pci1234[i] & 1) != 1 ) continue;
		u8 c;
		if(i < 7) {
			c  = (u8) ('4' + i - 1);
		}
		else {
			c  = (u8) ('A' + i - 1 - 6);
		}
		current = ALIGN(current, 8);
		printk(BIOS_DEBUG, "ACPI:    * SSDT for PCI%c Aka hcid = %d\n", c, sysconf.hcid[i]); /* pci0 and pci1 are in dsdt */
		ssdtx = (acpi_header_t *)current;
		switch(sysconf.hcid[i]) {
		case 1: /* 8132 */
			file_name = CONFIG_CBFS_PREFIX "/ssdt2.aml";
			break;
		case 2: /* 8151 */
			file_name = CONFIG_CBFS_PREFIX "/ssdt3.aml";
			break;
		case 3: /* 8131 */
			file_name = CONFIG_CBFS_PREFIX "/ssdt4.aml";
			break;
		default:
			continue;
		}
		p = cbfs_boot_map_with_leak(
					  file_name,
					  CBFS_TYPE_RAW, &p_size);
		if (!p || p_size < sizeof(acpi_header_t))
			continue;

		memcpy(ssdtx, p, sizeof(acpi_header_t));
		current += ssdtx->length;
		memcpy(ssdtx, p, ssdtx->length);
		update_ssdtx((void *)ssdtx, i);
		ssdtx->checksum = 0;
		ssdtx->checksum = acpi_checksum((u8 *)ssdtx, ssdtx->length);
		acpi_add_table(rsdp, ssdtx);
	}

	return current;
}
Esempio n. 6
0
/* Copy SPD data for on-board memory */
static void copy_spd(struct pei_data *peid)
{
	const int gpio_vector[] = {13, 9, 47, -1};
	int spd_index = get_gpios(gpio_vector);
	char *spd_file;
	size_t spd_file_len;

	printk(BIOS_DEBUG, "SPD index %d\n", spd_index);
	spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD,
						&spd_file_len);
	if (!spd_file)
		die("SPD data not found.");

	if (spd_file_len <
	    ((spd_index + 1) * sizeof(peid->spd_data[0]))) {
		printk(BIOS_ERR, "SPD index override to 0 - old hardware?\n");
		spd_index = 0;
	}

	if (spd_file_len < sizeof(peid->spd_data[0]))
		die("Missing SPD data.");

	/* Index 0-2, are 4GB config with both CH0 and CH1
	 * Index 3-5, are 2GB config with CH0 only
	 */
	switch (spd_index) {
	case 3: case 4: case 5:
		peid->dimm_channel1_disabled = 3;
	}

	memcpy(peid->spd_data[0],
	       spd_file +
	       spd_index * sizeof(peid->spd_data[0]),
	       sizeof(peid->spd_data[0]));
}
Esempio n. 7
0
uintptr_t mainboard_get_spd_data(void)
{
	char *spd_file;
	size_t spd_file_len;
	int spd_index;

	spd_index = mainboard_get_spd_index();
	printk(BIOS_INFO, "SPD index %d\n", spd_index);

	/* Load SPD data from CBFS */
	spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD,
		&spd_file_len);
	if (!spd_file)
		die("SPD data not found.");

	/* make sure we have at least one SPD in the file. */
	if (spd_file_len < SPD_LEN)
		die("Missing SPD data.");

	/* Make sure we did not overrun the buffer */
	if (spd_file_len < ((spd_index + 1) * SPD_LEN)) {
		printk(BIOS_ERR, "SPD index override to 1 - old hardware?\n");
		spd_index = 1;
	}

	spd_index *= SPD_LEN;
	mainboard_print_spd_info((uint8_t *)(spd_file + spd_index));

	return (uintptr_t)(spd_file + spd_index);
}
Esempio n. 8
0
/* Copy SPD data for on-board memory */
static void copy_spd(struct pei_data *peid)
{
	const int gpio_vector[] = {13, 9, 47, -1};
	int spd_index = get_gpios(gpio_vector);
	char *spd_file;
	size_t spd_file_len;

	printk(BIOS_DEBUG, "SPD index %d\n", spd_index);
	spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD,
						&spd_file_len);
	if (!spd_file)
		die("SPD data not found.");

	if (spd_file_len <
	    ((spd_index + 1) * sizeof(peid->spd_data[0]))) {
		printk(BIOS_ERR, "SPD index override to 0 - old hardware?\n");
		spd_index = 0;
	}

	if (spd_file_len < sizeof(peid->spd_data[0]))
		die("Missing SPD data.");

	memcpy(peid->spd_data[0],
	       spd_file +
	       spd_index * sizeof(peid->spd_data[0]),
	       sizeof(peid->spd_data[0]));
}
Esempio n. 9
0
/* Copy SPD data for on-board memory */
static void copy_spd(struct pei_data *peid)
{
	char *spd_file;
	size_t spd_file_len;
	int spd_index = 0; /* No GPIO selection, force index 0 for now */

	printk(BIOS_DEBUG, "SPD index %d\n", spd_index);
	spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD,
						&spd_file_len);
	if (!spd_file)
		die("SPD data not found.");

	if (spd_file_len <
	    ((spd_index + 1) * sizeof(peid->spd_data[0]))) {
		printk(BIOS_ERR, "SPD index override to 0 - old hardware?\n");
		spd_index = 0;
	}

	if (spd_file_len < sizeof(peid->spd_data[0]))
		die("Missing SPD data.");

	memcpy(peid->spd_data[0],
	       spd_file +
	       spd_index * sizeof(peid->spd_data[0]),
	       sizeof(peid->spd_data[0]));
}
Esempio n. 10
0
unsigned long mainboard_write_acpi_tables(struct device *device,
					  unsigned long current,
					  acpi_rsdp_t *rsdp)
{
	acpi_header_t *ssdtx;
	const void *p;
	size_t p_size;

	int i;

	/* same htio, but different possition? We may have to copy,
	 * change HCIN, and recalculate the checknum and add_table
	 */

	for (i = 1; i < sysconf.hc_possible_num; i++) {  /* 0: is hc sblink */
		const char *file_name;
		if ((sysconf.pci1234[i] & 1) != 1)
			continue;
		u8 c;
		if (i < 7) {
			c  = (u8) ('4' + i - 1);
		}
		else {
			c  = (u8) ('A' + i - 1 - 6);
		}
		current = ALIGN(current, 8);
		printk(BIOS_DEBUG, "ACPI:    * SSDT for PCI%c at %lx\n", c, current); /* pci0 and pci1 are in dsdt */
		ssdtx = (acpi_header_t *)current;
		switch (sysconf.hcid[i]) {
		case 1:
			file_name = CONFIG_CBFS_PREFIX "/ssdt2.aml";
			break;
		case 2:
			file_name = CONFIG_CBFS_PREFIX "/ssdt3.aml";
			break;
		case 3: /* 8131 */
			file_name = CONFIG_CBFS_PREFIX "/ssdt4.aml";
			break;
		default:
			/* HTX no io apic */
			file_name = CONFIG_CBFS_PREFIX "/ssdt5.aml";
		}
		p = cbfs_boot_map_with_leak(
					  file_name,
					  CBFS_TYPE_RAW, &p_size);
		if (!p || p_size < sizeof(acpi_header_t))
			continue;
		memcpy(ssdtx, p, sizeof(acpi_header_t));
		current += ssdtx->length;
		memcpy(ssdtx, p, ssdtx->length);
		update_ssdtx((void *)ssdtx, i);
		ssdtx->checksum = 0;
		ssdtx->checksum = acpi_checksum((u8 *)ssdtx, ssdtx->length);
		acpi_add_table(rsdp, ssdtx);
	}

	return current;
}
Esempio n. 11
0
AGESA_STATUS agesa_GfxGetVbiosImage(UINT32 Func, UINT32 FchData, VOID *ConfigPrt)
{
	GFX_VBIOS_IMAGE_INFO  *pVbiosImageInfo = (GFX_VBIOS_IMAGE_INFO *)ConfigPrt;
	pVbiosImageInfo->ImagePtr = cbfs_boot_map_with_leak(
			"pci"CONFIG_VGA_BIOS_ID".rom",
			CBFS_TYPE_OPTIONROM, NULL);
	printk(BIOS_DEBUG, "agesa_GfxGetVbiosImage: IMGptr=%p\n", pVbiosImageInfo->ImagePtr);
	return (pVbiosImageInfo->ImagePtr ? AGESA_SUCCESS : AGESA_WARNING);
}
Esempio n. 12
0
static u32 get_mrc_cache_region(struct mrc_data_container **mrc_region_ptr)
{
	size_t region_size;
	*mrc_region_ptr = cbfs_boot_map_with_leak("mrc.cache",
							CBFS_TYPE_MRC_CACHE,
							&region_size);

	return region_size;
}
Esempio n. 13
0
/* Copy SPD data for on-board memory */
void mainboard_fill_spd_data(struct pei_data *pei_data)
{
	char *spd_file;
	size_t spd_file_len;
	int spd_index, sku_id;

	gpio_t spd_gpios[] = {
		GPIO_MEM_CONFIG_0,
		GPIO_MEM_CONFIG_1,
		GPIO_MEM_CONFIG_2,
		GPIO_MEM_CONFIG_3,
	};

	spd_index = gpio_base2_value(spd_gpios, ARRAY_SIZE(spd_gpios));
	/*
	 * XXX: This is incorrect usage.The Board ID should be the revision ID
	 *      and not SKU ID but on SCRD it indicates SKU.
	 */
	sku_id = board_id();
	printk(BIOS_INFO, "SPD index %d\n", spd_index);
	printk(BIOS_INFO, "Board ID %d\n", sku_id);

	/* Load SPD data from CBFS */
	spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD,
		&spd_file_len);
	if (!spd_file)
		die("SPD data not found.");

	/* make sure we have at least one SPD in the file. */
	if (spd_file_len < SPD_LEN)
		die("Missing SPD data.");

	/* Make sure we did not overrun the buffer */
	if (spd_file_len < ((spd_index + 1) * SPD_LEN)) {
		printk(BIOS_ERR, "SPD index override to 0 - old hardware?\n");
		spd_index = 0;
	}

	/* Assume same memory in both channels */
	spd_index *= SPD_LEN;
	memcpy(pei_data->spd_data[0][0], spd_file + spd_index, SPD_LEN);
	/*
	 * XXX: This is incorrect usage. mem_cfg should be used here instead of
	 *	SKU ID. The current implementation of mem_config does not
	 *	support channel population.
	 */

	if (sku_id != SCRD_SKU1)
		memcpy(pei_data->spd_data[1][0], spd_file + spd_index, SPD_LEN);

	/* Make sure a valid SPD was found */
	if (pei_data->spd_data[0][0][0] == 0)
		die("Invalid SPD data.");

	mainboard_print_spd_info(pei_data->spd_data[0][0]);
}
Esempio n. 14
0
/* Copy SPD data for on-board memory */
void mainboard_fill_spd_data(struct pei_data *pei_data)
{
	int spd_bits[3] = {
		SPD_GPIO_BIT0,
		SPD_GPIO_BIT1,
		SPD_GPIO_BIT2
	};
	int spd_gpio[3];
	int spd_index;
	size_t spd_file_len;
	char *spd_file;

	spd_gpio[0] = get_gpio(SPD_GPIO_BIT0);
	spd_gpio[1] = get_gpio(SPD_GPIO_BIT1);
	spd_gpio[2] = get_gpio(SPD_GPIO_BIT2);

	spd_index = spd_gpio[2] << 2 | spd_gpio[1] << 1 | spd_gpio[0];

	printk(BIOS_DEBUG, "SPD: index %d (GPIO%d=%d GPIO%d=%d GPIO%d=%d)\n",
	       spd_index,
	       spd_bits[2], spd_gpio[2],
	       spd_bits[1], spd_gpio[1],
	       spd_bits[0], spd_gpio[0]);

	spd_file = cbfs_boot_map_with_leak("spd.bin", 0xab, &spd_file_len);
	if (!spd_file)
		die("SPD data not found.");

	if (spd_file_len < ((spd_index + 1) * SPD_LEN)) {
		printk(BIOS_ERR, "SPD index override to 0 - old hardware?\n");
		spd_index = 0;
	}

	if (spd_file_len < SPD_LEN)
		die("Missing SPD data.");

	memcpy(pei_data->spd_data[0][0],
		spd_file + (spd_index * SPD_LEN), SPD_LEN);
	/* Index 0-2 are 4GB config with both CH0 and CH1.
	 * Index 4-6 are 2GB config with CH0 only. */
	if (spd_index > 3)
		pei_data->dimm_channel1_disabled = 3;
	else
		memcpy(pei_data->spd_data[1][0],
			spd_file + (spd_index * SPD_LEN), SPD_LEN);

	/* Make sure a valid SPD was found */
	if (pei_data->spd_data[0][0][0] == 0)
		die("Invalid SPD data.");

	mainboard_print_spd_info(pei_data->spd_data[0][0]);
}
Esempio n. 15
0
AGESA_STATUS agesa_GfxGetVbiosImage(uint32_t Func, uintptr_t FchData,
							void *ConfigPrt)
{
	GFX_VBIOS_IMAGE_INFO *pVbiosImageInfo;

	pVbiosImageInfo = (GFX_VBIOS_IMAGE_INFO *)ConfigPrt;
	pVbiosImageInfo->ImagePtr = cbfs_boot_map_with_leak(
			"pci"CONFIG_VGA_BIOS_ID".rom",
			CBFS_TYPE_OPTIONROM, NULL);
	printk(BIOS_DEBUG, "%s: IMGptr=%p\n", __func__,
			pVbiosImageInfo->ImagePtr);
	return pVbiosImageInfo->ImagePtr ? AGESA_SUCCESS : AGESA_WARNING;
}
Esempio n. 16
0
void mainboard_get_spd(spd_raw_data *spd, bool id_only)
{
	/* C1S0 is a soldered RAM with no real SPD. Use stored SPD.  */
	size_t spd_file_len = 0;
	void *spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD,
		&spd_file_len);

	if (!spd_file || spd_file_len < sizeof(spd_raw_data))
		die("SPD data for C1S0 not found.");

	read_spd(&spd[0], 0x50, id_only);
	memcpy(&spd[2], spd_file, spd_file_len);
}
Esempio n. 17
0
/* Copy SPD data for on-board memory */
void mainboard_fill_spd_data(struct pei_data *pei_data)
{
    int spd_bits[4] = {
        SPD_GPIO_BIT0,
        SPD_GPIO_BIT1,
        SPD_GPIO_BIT2,
        SPD_GPIO_BIT3
    };
    int spd_gpio[4];
    int spd_index;
    size_t spd_file_len;
    char *spd_file;

    spd_gpio[0] = get_gpio(spd_bits[0]);
    spd_gpio[1] = get_gpio(spd_bits[1]);
    spd_gpio[2] = get_gpio(spd_bits[2]);
    spd_gpio[3] = get_gpio(spd_bits[3]);

    spd_index = (spd_gpio[3] << 3) | (spd_gpio[2] << 2) |
                (spd_gpio[1] << 1) | spd_gpio[0];

    printk(BIOS_DEBUG, "SPD: index %d (GPIO%d=%d GPIO%d=%d "
           "GPIO%d=%d GPIO%d=%d)\n", spd_index,
           spd_bits[3], spd_gpio[3], spd_bits[2], spd_gpio[2],
           spd_bits[1], spd_gpio[1], spd_bits[0], spd_gpio[0]);

    spd_file = cbfs_boot_map_with_leak("spd.bin", 0xab, &spd_file_len);
    if (!spd_file)
        die("SPD data not found.");

    if (spd_file_len < ((spd_index + 1) * SPD_LEN)) {
        printk(BIOS_ERR, "SPD index override to 0 - old hardware?\n");
        spd_index = 0;
    }

    if (spd_file_len < SPD_LEN)
        die("Missing SPD data.");

    /* Assume same memory in both channels */
    spd_index *= SPD_LEN;
    memcpy(pei_data->spd_data[0][0], spd_file + spd_index, SPD_LEN);
    memcpy(pei_data->spd_data[1][0], spd_file + spd_index, SPD_LEN);

    /* Make sure a valid SPD was found */
    if (pei_data->spd_data[0][0][0] == 0)
        die("Invalid SPD data.");

    mainboard_print_spd_info(pei_data->spd_data[0][0]);
}
Esempio n. 18
0
/* Copy SPD data for on-board memory */
void mainboard_fill_spd_data(struct pei_data *ps)
{
	char *spd_file;
	size_t spd_file_len;
	void *spd_content;
	int dual_channel = 0;

	/* Find the SPD data in CBFS. */
	spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD,
		&spd_file_len);
	if (!spd_file)
		die("SPD data not found.");

	if (spd_file_len < SPD_PAGE_LEN)
		die("Missing SPD data.");

	/*
	 * Both channels are always present in SPD data. Always use matched
	 * DIMMs so use the same SPD data for each DIMM.
	 */
	spd_content = get_spd_pointer(spd_file,
				      spd_file_len / SPD_PAGE_LEN,
				      &dual_channel);
	if (IS_ENABLED(CONFIG_DISPLAY_SPD_DATA) && spd_content != NULL) {
		printk(BIOS_DEBUG, "SPD Data:\n");
		hexdump(spd_content, SPD_PAGE_LEN);
		printk(BIOS_DEBUG, "\n");
	}

	/*
	 * Set SPD and memory configuration:
	 * Memory type: 0=DimmInstalled,
	 *              1=SolderDownMemory,
	 *              2=DimmDisabled
	 */
	if (spd_content != NULL) {
		ps->spd_data_ch0 = spd_content;
		ps->spd_ch0_config = 1;
		printk(BIOS_DEBUG, "Channel 0 DIMM soldered down\n");
		if (dual_channel) {
			printk(BIOS_DEBUG, "Channel 1 DIMM soldered down\n");
			ps->spd_data_ch1 = spd_content;
			ps->spd_ch1_config = 1;
		} else {
			printk(BIOS_DEBUG, "Channel 1 DIMM not installed\n");
			ps->spd_ch1_config = 2;
		}
	}
}
Esempio n. 19
0
const void *agesawrapper_locate_module (const CHAR8 name[8])
{
	const void* agesa;
	const AMD_IMAGE_HEADER* image;
	const AMD_MODULE_HEADER* module;
	size_t file_size;

	agesa = cbfs_boot_map_with_leak((const char *)CONFIG_CBFS_AGESA_NAME,
					CBFS_TYPE_RAW, &file_size);
	if (!agesa)
		return NULL;
	image =  LibAmdLocateImage(agesa, agesa + file_size - 1, 4096, name);
	module = (AMD_MODULE_HEADER*)image->ModuleInfoOffset;

	return module;
}
Esempio n. 20
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)
{
	unsigned long entry;

	printk(BIOS_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 (!vboot_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) {
		post_code(POST_RESUME_FAILURE);
		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 = (unsigned long)cbfs_boot_map_with_leak("mrc.bin",
							CBFS_TYPE_MRC, NULL);
	if (entry) {
		int rv;
		asm volatile (
			      "call *%%ecx\n\t"
			      :"=a" (rv) : "c" (entry), "a" (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 {
Esempio n. 21
0
static void vga_init(device_t dev)
{
	printk(BIOS_INFO, "Starting Graphics Initialization\n");
	size_t mbi_len;
	void *mbi = cbfs_boot_map_with_leak("mbi.bin", CBFS_TYPE_MBI, &mbi_len);

	if (mbi && mbi_len) {
		/* The GDT or coreboot table is going to live here. But
		 * a long time after we relocated the GNVS, so this is
		 * not troublesome.
		 */
		*(u32 *)0x500 = (u32)mbi;
		*(u32 *)0x504 = (u32)mbi_len;
		outb(0xeb, 0xb2);
	}

	pci_dev_init(dev);
	printk(BIOS_INFO, "Graphics Initialization Complete\n");

	/* Enable TV-Out */
#if CONFIG_PCI_OPTION_ROM_RUN_YABEL
#define PIPE_A_CRT	(1 << 0)
#define PIPE_A_LFP	(1 << 1)
#define PIPE_A_TV	(1 << 3)
#define PIPE_B_CRT	(1 << 8)
#define PIPE_B_TV	(1 << 10)
	printk(BIOS_DEBUG, "Enabling TV-Out\n");
	void runInt10(void);
	X86_AX = 0x5f64;
	X86_BX = 0x0001; // Set Display Device, force execution
	X86_CX = PIPE_A_CRT | PIPE_A_TV;
	// M.x86.R_CX = PIPE_B_TV;
	runInt10();
	switch (X86_AX) {
	case 0x005f:
		printk(BIOS_DEBUG, "... failed.\n");
		break;
	case 0x015f:
		printk(BIOS_DEBUG, "... ok.\n");
		break;
	default:
		printk(BIOS_DEBUG, "... not supported.\n");
		break;
	}
#endif
}
Esempio n. 22
0
/* Copy SPD data for on-board memory */
static void copy_spd(struct pei_data *peid)
{
	const int gpio_vector[] = {13, 9, 47, -1};
	int spd_index = get_gpios(gpio_vector);
	char *spd_file;
	size_t spd_file_len;

	printk(BIOS_DEBUG, "SPD index %d\n", spd_index);
	spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD,
						&spd_file_len);
	if (!spd_file)
		die("SPD data not found.");

	switch (google_chromeec_get_board_version()) {
	case PEPPY_BOARD_VERSION_PROTO:
		/* Index 0 is 2GB config with CH0 only. */
		if (spd_index == 0)
			peid->dimm_channel1_disabled = 3;
		break;

	case PEPPY_BOARD_VERSION_EVT:
	default:
		/* Index 0-2 are 4GB config with both CH0 and CH1.
		 * Index 4-6 are 2GB config with CH0 only. */
		if (spd_index > 3)
			peid->dimm_channel1_disabled = 3;
		break;
	}

	if (spd_file_len <
	    ((spd_index + 1) * sizeof(peid->spd_data[0]))) {
		printk(BIOS_ERR, "SPD index override to 0 - old hardware?\n");
		spd_index = 0;
	}

	if (spd_file_len < sizeof(peid->spd_data[0]))
		die("Missing SPD data.");

	memcpy(peid->spd_data[0],
	       spd_file +
	       spd_index * sizeof(peid->spd_data[0]),
	       sizeof(peid->spd_data[0]));
}
Esempio n. 23
0
/* Right now, the offsets for the MRC cache area are hard-coded in the
 * northbridge Kconfig if CONFIG_CHROMEOS is not set. In order to make
 * this more flexible, there are two of options:
 *  - Have each mainboard Kconfig supply a hard-coded offset
 *  - Use CBFS
 */
static u32 get_mrc_cache_region(struct mrc_data_container **mrc_region_ptr)
{
	size_t region_size = 0;
	*mrc_region_ptr = NULL;

	if (IS_ENABLED(CONFIG_CHROMEOS)) {
		struct region_device rdev;

		if (fmap_locate_area_as_rdev("RW_MRC_CACHE", &rdev) == 0) {
			region_size = region_device_sz(&rdev);
			*mrc_region_ptr = rdev_mmap_full(&rdev);
		}
	} else {
		*mrc_region_ptr = cbfs_boot_map_with_leak("mrc.cache",
							CBFS_TYPE_MRC_CACHE,
							&region_size);
	}
	return region_size;
}
Esempio n. 24
0
static void program_mac_address(u16 io_base)
{
	void *search_address = NULL;
	size_t search_length = -1;

	/* Default MAC Address of A0:00:BA:D0:0B:AD */
	u32 high_dword = 0xD0BA00A0;	/* high dword of mac address */
	u32 low_dword = 0x0000AD0B;	/* low word of mac address as a dword */

	if (IS_ENABLED(CONFIG_CHROMEOS)) {
		struct region_device rdev;

		if (fmap_locate_area_as_rdev("RO_VPD", &rdev) == 0) {
			search_address = rdev_mmap_full(&rdev);

			if (search_address != NULL)
				search_length = region_device_sz(&rdev);
		}
	} else {
		search_address = cbfs_boot_map_with_leak("vpd.bin",
							CBFS_TYPE_RAW,
							&search_length);
	}

	if (search_address == NULL)
		printk(BIOS_ERR, "LAN: VPD not found.\n");
	else
		get_mac_address(&high_dword, &low_dword, search_address,
				search_length);

	if (io_base) {
		printk(BIOS_DEBUG, "Realtek NIC io_base = 0x%04x\n", io_base);
		printk(BIOS_DEBUG, "Programming MAC Address\n");

		/* Disable register protection */
		outb(0xc0, io_base + 0x50);
		outl(high_dword, io_base);
		outl(low_dword, io_base + 0x04);
		outb(0x60, io_base + 54);
		/* Enable register protection again */
		outb(0x00, io_base + 0x50);
	}
}
Esempio n. 25
0
/* Copy SPD data for on-board memory */
void mainboard_fill_spd_data(struct pei_data *pei_data)
{
	char *spd_file;
	size_t spd_file_len;
	int spd_index;

	gpio_t spd_gpios[] = {
		GPIO_MEM_CONFIG_0,
		GPIO_MEM_CONFIG_1,
		GPIO_MEM_CONFIG_2,
		GPIO_MEM_CONFIG_3,
	};

	spd_index = gpio_base2_value(spd_gpios, ARRAY_SIZE(spd_gpios));
	printk(BIOS_INFO, "SPD index %d\n", spd_index);

	/* Load SPD data from CBFS */
	spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD,
		&spd_file_len);
	if (!spd_file)
		die("SPD data not found.");

	/* make sure we have at least one SPD in the file. */
	if (spd_file_len < SPD_LEN)
		die("Missing SPD data.");

	/* Make sure we did not overrun the buffer */
	if (spd_file_len < ((spd_index + 1) * SPD_LEN)) {
		printk(BIOS_ERR, "SPD index override to 1 - old hardware?\n");
		spd_index = 1;
	}

	/* Assume same memory in both channels */
	spd_index *= SPD_LEN;
	memcpy(pei_data->spd_data[0][0], spd_file + spd_index, SPD_LEN);
	memcpy(pei_data->spd_data[1][0], spd_file + spd_index, SPD_LEN);

	/* Make sure a valid SPD was found */
	if (pei_data->spd_data[0][0][0] == 0)
		die("Invalid SPD data.");

	mainboard_print_spd_info(pei_data->spd_data[0][0]);
}
Esempio n. 26
0
void amd_update_microcode_from_cbfs(uint32_t equivalent_processor_rev_id)
{
	const void *ucode;
	size_t ucode_len;

	uint32_t i;

	for (i = 0; i < ARRAY_SIZE(microcode_cbfs_file); i++)
	{
		if (equivalent_processor_rev_id == 0) {
			UCODE_DEBUG("rev id not found. Skipping microcode patch!\n");
			return;
		}

#ifdef __PRE_RAM__
#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK)
		spin_lock(romstage_microcode_cbfs_lock());
#endif
#endif

		ucode = cbfs_boot_map_with_leak(microcode_cbfs_file[i],
						CBFS_TYPE_MICROCODE, &ucode_len);
		if (!ucode) {
			UCODE_DEBUG("microcode file not found. Skipping updates.\n");
#ifdef __PRE_RAM__
#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK)
			spin_unlock(romstage_microcode_cbfs_lock());
#endif
#endif
			return;
		}

		amd_update_microcode(ucode, ucode_len, equivalent_processor_rev_id);

#ifdef __PRE_RAM__
#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK)
		spin_unlock(romstage_microcode_cbfs_lock());
#endif
#endif
	}
}
Esempio n. 27
0
static uint8_t *locate_spd(void)
{
	const int gpio_vector[] = {41, 42, 43, 10, -1};
	uint8_t *spd_file;
	size_t spd_file_len;
	int spd_index = get_gpios(gpio_vector);

	printk(BIOS_DEBUG, "spd index %d\n", spd_index);
	spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD,
						&spd_file_len);
	if (!spd_file)
		die("SPD data not found.");

	if (spd_file_len < ((spd_index + 1) * 256)) {
		printk(BIOS_ERR, "spd index override to 0 - old hardware?\n");
		spd_index = 0;
	}

	if (spd_file_len < 256)
		die("Missing SPD data.");

	return spd_file + spd_index * 256;
}
Esempio n. 28
0
/* Copy SPD data for on-board memory */
void mainboard_fill_spd_data(struct pei_data *pei_data)
{
	char *spd_file;
	size_t spd_file_len;
	int spd_index;

	/* Find the SPD data in CBFS. */
	spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD,
		&spd_file_len);
	if (!spd_file)
		die("SPD data not found.");

	/* make sure we have at least one SPD in the file. */
	if (spd_file_len < SPD_LEN)
		die("Missing SPD data.");

	/* Add board SKU detection here.  Currently we only support one. */
	spd_index = 0;

	/* Make sure we did not overrun the buffer */
	if (spd_file_len < ((spd_index + 1) * SPD_LEN)) {
		printk(BIOS_ERR, "SPD index override to 0 - old hardware?\n");
		spd_index = 0;
	}

	/* Assume same memory in both channels */
	spd_index *= SPD_LEN;
	memcpy(pei_data->spd_data[0][0], spd_file + spd_index, SPD_LEN);
	memcpy(pei_data->spd_data[1][0], spd_file + spd_index, SPD_LEN);

	/* Make sure a valid SPD was found */
	if (pei_data->spd_data[0][0][0] == 0)
		die("Invalid SPD data.");

	mainboard_print_spd_info(pei_data->spd_data[0][0]);
}
Esempio n. 29
0
/* Initialize the UPD parameters for MemoryInit */
void soc_memory_init_params(struct romstage_params *params,
			    MEMORY_INIT_UPD *upd)
{
	const struct device *dev;
	const struct soc_intel_quark_config *config;
	struct chipset_power_state *ps = car_get_var_ptr(&power_state);
	char *rmu_file;
	size_t rmu_file_len;

	/* Locate the configuration data from devicetree.cb */
	dev = dev_find_slot(0, LPC_DEV_FUNC);
	if (!dev) {
		printk(BIOS_ERR,
			"Error! Device (PCI:0:%02x.%01x) not found, "
			"soc_memory_init_params!\n", PCI_DEVICE_NUMBER_QNC_LPC,
			PCI_FUNCTION_NUMBER_QNC_LPC);
		return;
	}
	config = dev->chip_info;

	/* Display the ROM shadow data */
	hexdump((void *)0x000ffff0, 0x10);

	/* Clear SMI and wake events */
	if (ps->prev_sleep_state != ACPI_S3) {
		printk(BIOS_SPEW, "Clearing SMI interrupts and wake events\n");
		reg_script_run_on_dev(LPC_BDF, clear_smi_and_wake_events);
	}

	/* Locate the RMU data file in flash */
	rmu_file = cbfs_boot_map_with_leak("rmu.bin", CBFS_TYPE_RAW,
		&rmu_file_len);
	if (!rmu_file)
		die("Microcode file (rmu.bin) not found.");

	/* Update the UPD data for MemoryInit */
	printk(BIOS_DEBUG, "Updating UPD values for MemoryInit: 0x%p\n", upd);
	upd->AddrMode = config->AddrMode;
	upd->ChanMask = config->ChanMask;
	upd->ChanWidth = config->ChanWidth;
	upd->DramDensity = config->DramDensity;
	upd->DramRonVal = config->DramRonVal;
	upd->DramRttNomVal = config->DramRttNomVal;
	upd->DramRttWrVal = config->DramRttWrVal;
	upd->DramSpeed = config->DramSpeed;
	upd->DramType = config->DramType;
	upd->DramWidth = config->DramWidth;
	upd->EccScrubBlkSize = config->EccScrubBlkSize;
	upd->EccScrubInterval = config->EccScrubInterval;
	upd->Flags = config->Flags;
	upd->FspReservedMemoryLength = config->FspReservedMemoryLength;
	upd->RankMask = config->RankMask;
	upd->RmuBaseAddress = (uintptr_t)rmu_file;
	upd->RmuLength = rmu_file_len;
	upd->SerialPortBaseAddress = UART_BASE_ADDRESS;
	upd->SmmTsegSize = IS_ENABLED(CONFIG_HAVE_SMI_HANDLER) ?
		config->SmmTsegSize : 0;
	upd->SocRdOdtVal = config->SocRdOdtVal;
	upd->SocWrRonVal = config->SocWrRonVal;
	upd->SocWrSlewRate = config->SocWrSlewRate;
	upd->SrInt = config->SrInt;
	upd->SrTemp = config->SrTemp;
	upd->tCL = config->tCL;
	upd->tFAW = config->tFAW;
	upd->tRAS = config->tRAS;
	upd->tRRD = config->tRRD;
	upd->tWTR = config->tWTR;
}
Esempio n. 30
0
unsigned long write_coreboot_table(
	unsigned long low_table_start, unsigned long low_table_end,
	unsigned long rom_table_start, unsigned long rom_table_end)
{
	struct lb_header *head;

	if (low_table_start || low_table_end) {
		printk(BIOS_DEBUG, "Writing table forward entry at 0x%08lx\n",
				low_table_end);
		head = lb_table_init(low_table_end);
		lb_forward(head, (struct lb_header*)rom_table_end);

		low_table_end = (unsigned long) lb_table_fini(head);
		printk(BIOS_DEBUG, "Table forward entry ends at 0x%08lx.\n",
			low_table_end);
		low_table_end = ALIGN(low_table_end, 4096);
		printk(BIOS_DEBUG, "... aligned to 0x%08lx\n", low_table_end);
	}

	printk(BIOS_DEBUG, "Writing coreboot table at 0x%08lx\n",
		rom_table_end);

	head = lb_table_init(rom_table_end);
	rom_table_end = (unsigned long)head;
	printk(BIOS_DEBUG, "rom_table_end = 0x%08lx\n", rom_table_end);
	rom_table_end = ALIGN(rom_table_end, (64 * 1024));
	printk(BIOS_DEBUG, "... aligned to 0x%08lx\n", rom_table_end);

#if CONFIG_USE_OPTION_TABLE
	{
		struct cmos_option_table *option_table =
			cbfs_boot_map_with_leak("cmos_layout.bin",
				CBFS_COMPONENT_CMOS_LAYOUT, NULL);
		if (option_table) {
			struct lb_record *rec_dest = lb_new_record(head);
			/* Copy the option config table, it's already a lb_record... */
			memcpy(rec_dest,  option_table, option_table->size);
			/* Create cmos checksum entry in coreboot table */
			lb_cmos_checksum(head);
		} else {
			printk(BIOS_ERR, "cmos_layout.bin could not be found!\n");
		}
	}
#endif

	/* Initialize the memory map at boot time. */
	bootmem_init();

	if (low_table_start || low_table_end) {
		uint64_t size = low_table_end - low_table_start;
		/* Record the mptable and the the lb_table.
		 * (This will be adjusted later)  */
		bootmem_add_range(low_table_start, size, LB_MEM_TABLE);
	}

	/* Record the pirq table, acpi tables, and maybe the mptable. However,
	 * these only need to be added when the rom_table is sitting below
	 * 1MiB. If it isn't that means high tables are being written.
	 * The code below handles high tables correctly. */
	if (rom_table_end <= (1 << 20)) {
		uint64_t size = rom_table_end - rom_table_start;
		bootmem_add_range(rom_table_start, size, LB_MEM_TABLE);
	}

	/* No other memory areas can be added after the memory table has been
	 * committed as the entries won't show up in the serialize mem table. */
	bootmem_write_memory_table(lb_memory(head));

	/* Record our motherboard */
	lb_mainboard(head);

	/* Record the serial ports and consoles */
#if CONFIG_CONSOLE_SERIAL
	uart_fill_lb(head);
#endif
#if CONFIG_CONSOLE_USB
	lb_add_console(LB_TAG_CONSOLE_EHCI, head);
#endif

	/* Record our various random string information */
	lb_strings(head);
	lb_record_version_timestamp(head);
	/* Record our framebuffer */
	lb_framebuffer(head);

#if CONFIG_CHROMEOS
	/* Record our GPIO settings (ChromeOS specific) */
	lb_gpios(head);

	/* pass along the VDAT buffer address */
	lb_vdat(head);

	/* pass along VBNV offsets in CMOS */
	lb_vbnv(head);

	/* pass along the vboot_handoff address. */
	lb_vboot_handoff(head);
#endif

	/* Add board ID if available */
	lb_board_id(head);

	/* Add RAM config if available */
	lb_ram_code(head);

#if IS_ENABLED(CONFIG_SPI_FLASH)
	/* Add SPI flash description if available */
	lb_spi_flash(head);
#endif

	add_cbmem_pointers(head);

	/* Add board-specific table entries, if any. */
	lb_board(head);

#if IS_ENABLED(CONFIG_CHROMEOS_RAMOOPS)
	lb_ramoops(head);
#endif

	lb_boot_media_params(head);

	/* Add all cbmem entries into the coreboot tables. */
	cbmem_add_records_to_cbtable(head);

	/* Remember where my valid memory ranges are */
	return lb_table_fini(head);
}