Beispiel #1
0
/* Save the DIMM information for SMBIOS table 17 */
void soc_save_dimm_info(void)
{
	int channel;
	const CHANNEL_INFO *channel_info;
	int dimm;
	const DIMM_INFO *dimm_info;
	int dimm_max;
	int index;
	struct memory_info *mem_info;
	const FSP_SMBIOS_MEMORY_INFO *memory_info_hob;

	/* Get the memory info HOB */
	memory_info_hob = soc_get_fsp_smbios_memory_info_hob();

	if (memory_info_hob == NULL)
		return;

	/* Display the data in the FSP_SMBIOS_MEMORY_INFO HOB */
	if (IS_ENABLED(CONFIG_DISPLAY_HOBS))
		soc_display_fsp_smbios_memory_info_hob(memory_info_hob);

	/*
	 * Allocate CBMEM area for DIMM information used to populate SMBIOS
	 * table 17
	 */
	mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info));
	printk(BIOS_DEBUG, "CBMEM entry for DIMM info: 0x%p\n", mem_info);
	if (mem_info == NULL)
		return;
	memset(mem_info, 0, sizeof(*mem_info));

	/* Describe the first N DIMMs in the system */
	index = 0;
	dimm_max = ARRAY_SIZE(mem_info->dimm);
	for (channel = 0; channel < memory_info_hob->ChannelCount; channel++) {
		if (index >= dimm_max)
			break;
		channel_info = &memory_info_hob->ChannelInfo[channel];
		for (dimm = 0; dimm < channel_info->DimmCount; dimm++) {
			if (index >= dimm_max)
				break;
			dimm_info = &channel_info->DimmInfo[dimm];

			/* Populate the DIMM information */
			if (!dimm_info->SizeInMb)
				continue;

			mem_info->dimm[index].dimm_size =
				dimm_info->SizeInMb;
			mem_info->dimm[index].ddr_type =
				memory_info_hob->MemoryType;
			mem_info->dimm[index].ddr_frequency =
				memory_info_hob->MemoryFrequencyInMHz;
			mem_info->dimm[index].channel_num =
				channel_info->ChannelId;
			mem_info->dimm[index].dimm_num =
				dimm_info->DimmId;

			strncpy((char *)
				mem_info->dimm[index].module_part_number,
				(char *)dimm_info->ModulePartNum, 18);
			mem_info->dimm[index].mod_id =
				dimm_info->MfgId;
			switch (memory_info_hob->DataWidth) {
			default:
			case 8:
				mem_info->dimm[index].bus_width =
					MEMORY_BUS_WIDTH_8;
				break;

			case 16:
				mem_info->dimm[index].bus_width =
					MEMORY_BUS_WIDTH_16;
				break;

			case 32:
				mem_info->dimm[index].bus_width =
					MEMORY_BUS_WIDTH_32;
				break;

			case 64:
				mem_info->dimm[index].bus_width =
					MEMORY_BUS_WIDTH_64;
				break;

			case 128:
				mem_info->dimm[index].bus_width =
					MEMORY_BUS_WIDTH_128;
				break;
			}

			/* Add any mainboard specific information */
			mainboard_add_dimm_info(mem_info, channel, dimm, index);
			index++;
		}
	}
	mem_info->dimm_cnt = index;
	printk(BIOS_DEBUG, "%d DIMMs found\n", mem_info->dimm_cnt);
}
Beispiel #2
0
/* Save the DIMM information for SMBIOS table 17 */
__attribute__((weak)) void mainboard_save_dimm_info(
	struct romstage_params *params)
{
	int channel;
	CHANNEL_INFO *channel_info;
	int dimm;
	DIMM_INFO *dimm_info;
	int dimm_max;
	void *hob_list_ptr;
	EFI_HOB_GUID_TYPE *hob_ptr;
	int index;
	struct memory_info *mem_info;
	FSP_SMBIOS_MEMORY_INFO *memory_info_hob;
	const EFI_GUID memory_info_hob_guid = FSP_SMBIOS_MEMORY_INFO_GUID;

	/* Locate the memory info HOB, presence validated by raminit */
	hob_list_ptr = fsp_get_hob_list();
	hob_ptr = get_next_guid_hob(&memory_info_hob_guid, hob_list_ptr);
	memory_info_hob = (FSP_SMBIOS_MEMORY_INFO *)(hob_ptr + 1);

	/* Display the data in the FSP_SMBIOS_MEMORY_INFO HOB */
	if (IS_ENABLED(CONFIG_DISPLAY_HOBS)) {
		printk(BIOS_DEBUG, "FSP_SMBIOS_MEMORY_INFO HOB\n");
		printk(BIOS_DEBUG, "    0x%02x: Revision\n",
			memory_info_hob->Revision);
		printk(BIOS_DEBUG, "    0x%02x: MemoryType\n",
			memory_info_hob->MemoryType);
		printk(BIOS_DEBUG, "    %d: MemoryFrequencyInMHz\n",
			memory_info_hob->MemoryFrequencyInMHz);
		printk(BIOS_DEBUG, "    %d: DataWidth in bits\n",
			memory_info_hob->DataWidth);
		printk(BIOS_DEBUG, "    0x%02x: ErrorCorrectionType\n",
			memory_info_hob->ErrorCorrectionType);
		printk(BIOS_DEBUG, "    0x%02x: ChannelCount\n",
			memory_info_hob->ChannelCount);
		for (channel = 0; channel < memory_info_hob->ChannelCount;
			channel++) {
			channel_info = &memory_info_hob->ChannelInfo[channel];
			printk(BIOS_DEBUG, "  Channel %d\n", channel);
			printk(BIOS_DEBUG, "      0x%02x: ChannelId\n",
				channel_info->ChannelId);
			printk(BIOS_DEBUG, "      0x%02x: DimmCount\n",
				channel_info->DimmCount);
			for (dimm = 0; dimm < channel_info->DimmCount;
				dimm++) {
				dimm_info = &channel_info->DimmInfo[dimm];
				printk(BIOS_DEBUG, "   DIMM %d\n", dimm);
				printk(BIOS_DEBUG, "      0x%02x: DimmId\n",
					dimm_info->DimmId);
				printk(BIOS_DEBUG, "      %d: SizeInMb\n",
					dimm_info->SizeInMb);
			}
		}
	}

	/*
	 * Allocate CBMEM area for DIMM information used to populate SMBIOS
	 * table 17
	 */
	mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info));
	printk(BIOS_DEBUG, "CBMEM entry for DIMM info: 0x%p\n", mem_info);
	if (mem_info == NULL)
		return;
	memset(mem_info, 0, sizeof(*mem_info));

	/* Describe the first N DIMMs in the system */
	index = 0;
	dimm_max = ARRAY_SIZE(mem_info->dimm);
	for (channel = 0; channel < memory_info_hob->ChannelCount; channel++) {
		if (index >= dimm_max)
			break;
		channel_info = &memory_info_hob->ChannelInfo[channel];
		for (dimm = 0; dimm < channel_info->DimmCount; dimm++) {
			if (index >= dimm_max)
				break;
			dimm_info = &channel_info->DimmInfo[dimm];

			/* Populate the DIMM information */
			if (dimm_info->SizeInMb) {
				mem_info->dimm[index].dimm_size =
					dimm_info->SizeInMb;
				mem_info->dimm[index].ddr_type =
					memory_info_hob->MemoryType;
				mem_info->dimm[index].ddr_frequency =
					memory_info_hob->MemoryFrequencyInMHz;
				mem_info->dimm[index].channel_num =
					channel_info->ChannelId;
				mem_info->dimm[index].dimm_num =
					dimm_info->DimmId;
				switch (memory_info_hob->DataWidth) {
				default:
				case 8:
					mem_info->dimm[index].bus_width =
						MEMORY_BUS_WIDTH_8;
					break;

				case 16:
					mem_info->dimm[index].bus_width =
						MEMORY_BUS_WIDTH_16;
					break;

				case 32:
					mem_info->dimm[index].bus_width =
						MEMORY_BUS_WIDTH_32;
					break;

				case 64:
					mem_info->dimm[index].bus_width =
						MEMORY_BUS_WIDTH_64;
					break;

				case 128:
					mem_info->dimm[index].bus_width =
						MEMORY_BUS_WIDTH_128;
					break;
				}

				/* Add any mainboard specific information */
				mainboard_add_dimm_info(params, mem_info,
							channel, dimm, index);
				index++;
			}
		}
	}
	mem_info->dimm_cnt = index;
	printk(BIOS_DEBUG, "%d DIMMs found\n", mem_info->dimm_cnt);
}