1a86cda6db
The DIMM manufacturing ID was not being initialized and so the DIMMs were not described in SMBIOS tables properly. The module type can also be provided, but the SMBIOS code expects SPD module type values from DDR2 so the DDR3/4 values are adjusted before sending to SMBIOS. BUG=b:134897498 BRANCH=sarien TEST=dump and compare with dmidecode BEFORE: Type: DDR4 Manufacturer: Unknown (0) Form Factor: Unknown AFTER: Type: DDR4 Manufacturer: Hynix/Hyundai Form Factor: SODIMM Change-Id: Id673e08aa6e3dad196009c3c21a3dda2f40c9e42 Signed-off-by: Duncan Laurie <dlaurie@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/33379 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Furquan Shaikh <furquan@google.com>
94 lines
2.6 KiB
C
94 lines
2.6 KiB
C
/*
|
|
* This file is part of the coreboot project.
|
|
*
|
|
* Copyright (C) 2017 Intel Inc.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; version 2 of the License.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#include <smbios.h>
|
|
#include "smbios.h"
|
|
#include <string.h>
|
|
#include <console/console.h>
|
|
#include <device/dram/ddr3.h>
|
|
|
|
/* Fill the SMBIOS memory information from FSP MEM_INFO_DATA_HOB in CBMEM.*/
|
|
void dimm_info_fill(struct dimm_info *dimm, u32 dimm_capacity, u8 ddr_type,
|
|
u32 frequency, u8 rank_per_dimm, u8 channel_id, u8 dimm_id,
|
|
const char *module_part_num, size_t module_part_number_size,
|
|
const u8 *module_serial_num, u16 data_width, u32 vdd_voltage,
|
|
bool ecc_support, u16 mod_id, u8 mod_type)
|
|
{
|
|
dimm->mod_id = mod_id;
|
|
/* Translate to DDR2 module type field that SMBIOS code expects. */
|
|
switch (mod_type) {
|
|
case SPD_DIMM_TYPE_SO_DIMM:
|
|
dimm->mod_type = SPD_SODIMM;
|
|
break;
|
|
case SPD_DIMM_TYPE_72B_SO_CDIMM:
|
|
dimm->mod_type = SPD_72B_SO_CDIMM;
|
|
break;
|
|
case SPD_DIMM_TYPE_72B_SO_RDIMM:
|
|
dimm->mod_type = SPD_72B_SO_RDIMM;
|
|
break;
|
|
case SPD_DIMM_TYPE_UDIMM:
|
|
dimm->mod_type = SPD_UDIMM;
|
|
break;
|
|
case SPD_DIMM_TYPE_RDIMM:
|
|
dimm->mod_type = SPD_RDIMM;
|
|
break;
|
|
case SPD_DIMM_TYPE_UNDEFINED:
|
|
default:
|
|
dimm->mod_type = SPD_UNDEFINED;
|
|
break;
|
|
}
|
|
dimm->dimm_size = dimm_capacity;
|
|
dimm->ddr_type = ddr_type;
|
|
dimm->ddr_frequency = frequency;
|
|
dimm->rank_per_dimm = rank_per_dimm;
|
|
dimm->channel_num = channel_id;
|
|
dimm->dimm_num = dimm_id;
|
|
if (vdd_voltage > 0xFFFF) {
|
|
dimm->vdd_voltage = 0xFFFF;
|
|
} else {
|
|
dimm->vdd_voltage = vdd_voltage;
|
|
}
|
|
|
|
strncpy((char *)dimm->module_part_number,
|
|
module_part_num,
|
|
min(sizeof(dimm->module_part_number),
|
|
module_part_number_size));
|
|
if (module_serial_num)
|
|
memcpy(dimm->serial, module_serial_num,
|
|
DIMM_INFO_SERIAL_SIZE);
|
|
switch (data_width) {
|
|
case 8:
|
|
dimm->bus_width = MEMORY_BUS_WIDTH_8;
|
|
break;
|
|
case 16:
|
|
dimm->bus_width = MEMORY_BUS_WIDTH_16;
|
|
break;
|
|
case 32:
|
|
dimm->bus_width = MEMORY_BUS_WIDTH_32;
|
|
break;
|
|
case 64:
|
|
dimm->bus_width = MEMORY_BUS_WIDTH_64;
|
|
break;
|
|
case 128:
|
|
dimm->bus_width = MEMORY_BUS_WIDTH_128;
|
|
break;
|
|
default:
|
|
printk(BIOS_NOTICE, "Incorrect DIMM Data width: %u\n",
|
|
(unsigned int)data_width);
|
|
}
|
|
|
|
if (ecc_support)
|
|
dimm->bus_width |= 0x8;
|
|
}
|