Piotr Kleinschmidt has uploaded this change for review.

View Change

mainboard/pcengines/apu2/mainboard.c: fill SMBIOS type 16 and 17

Change-Id: I24cd5abceabd11a079a8331e4b95cb69af8e94bf
Signed-off-by: Piotr Kleinschmidt <piotr.kleins@gmail.com>
---
M src/device/dram/Makefile.inc
M src/lib/Makefile.inc
M src/mainboard/pcengines/apu2/mainboard.c
3 files changed, 124 insertions(+), 0 deletions(-)

git pull ssh://review.coreboot.org:29418/coreboot refs/changes/89/35889/1
diff --git a/src/device/dram/Makefile.inc b/src/device/dram/Makefile.inc
index f397a53..d9df410 100644
--- a/src/device/dram/Makefile.inc
+++ b/src/device/dram/Makefile.inc
@@ -1 +1,2 @@
romstage-y += ddr4.c ddr3.c ddr2.c ddr_common.c
+ramstage-y += ddr4.c ddr3.c ddr2.c ddr_common.c
\ No newline at end of file
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc
index e5678ff..dc09851 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -328,6 +328,7 @@
endif # CONFIG_RAMSTAGE_LIBHWBASE

romstage-y += spd_bin.c
+ramstage-y += spd_bin.c

ifeq ($(CONFIG_GENERIC_SPD_BIN),y)
LIB_SPD_BIN = $(obj)/spd.bin
diff --git a/src/mainboard/pcengines/apu2/mainboard.c b/src/mainboard/pcengines/apu2/mainboard.c
index 682120b..1d91a39 100644
--- a/src/mainboard/pcengines/apu2/mainboard.c
+++ b/src/mainboard/pcengines/apu2/mainboard.c
@@ -27,6 +27,9 @@
#include <superio/nuvoton/nct5104d/nct5104d.h>
#include <smbios.h>
#include <string.h>
+#include <cbmem.h>
+#include <spd_bin.h>
+#include <cbfs.h>
#include "gpio_ftns.h"

#define SPD_SIZE 128
@@ -154,6 +157,81 @@
gpio->enabled = CONFIG(APU2_PINMUX_GPIO1);
}

+static void set_dimm_info(uint8_t *spd, struct dimm_info *dimm)
+{
+ const int spd_capmb[8] = { 1, 2, 4, 8, 16, 32, 64, 0 };
+ const int spd_ranks[8] = { 1, 2, 3, 4, -1, -1, -1, -1 };
+ const int spd_devw[8] = { 4, 8, 16, 32, -1, -1, -1, -1 };
+ const int spd_busw[8] = { 8, 16, 32, 64, -1, -1, -1, -1 };
+
+ int capmb = spd_capmb[spd[SPD_DENSITY_BANKS] & 7] * 256;
+ int ranks = spd_ranks[(spd[DDR3_ORGANIZATION] >> 3) & 7];
+ int devw = spd_devw[spd[DDR3_ORGANIZATION] & 7];
+ int busw = spd_busw[spd[DDR3_BUS_DEV_WIDTH] & 7];
+
+ switch (spd[12]) {
+ case 0x0a:
+ dimm->ddr_frequency = 1600;
+ break;
+ case 0x0c:
+ dimm->ddr_frequency = 1333;
+ break;
+ default:
+ dimm->ddr_frequency = 0;
+ break;
+ }
+
+ dimm->ddr_type = MEMORY_TYPE_DDR3;
+
+ /* Parse the SPD data to determine the DIMM information */
+
+ dimm->dimm_size = capmb / 8 * busw / devw * ranks; /* MiB */
+ dimm->mod_type = spd[3] & 0xf;
+ dimm->module_part_number[0] = '\0';
+ dimm->mod_id = *(uint16_t *)&spd[117];
+
+ switch (busw) {
+ default:
+ 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;
+ }
+
+ if(spd[3]==0x08){
+ dimm->bus_width |= BIOS_MEMORY_ECC_SINGLE_BIT_CORRECTING;
+ }
+}
+
+static void mainboard_get_dimm_info(u8 *spd_buffer)
+{
+ struct dimm_info *dimm;
+ struct memory_info *mem_info;
+
+ /*
+ * 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 channel memory */
+ dimm = &mem_info->dimm[0];
+ set_dimm_info(spd_buffer, dimm);
+ mem_info->dimm_cnt = 1;
+}
+
/**********************************************
* enable the dedicated function in mainboard.
**********************************************/
@@ -164,6 +242,11 @@

config_gpio_mux();

+ u8 spd_index = get_spd_offset();
+ u8 spd_buffer[CONFIG_DIMM_SPD_SIZE];
+
+ read_ddr3_spd_from_cbfs(spd_buffer, spd_index);
+
//
// Enable the RTC output
//
@@ -176,6 +259,8 @@

/* Initialize the PIRQ data structures for consumption */
pirq_setup();
+
+ mainboard_get_dimm_info(spd_buffer);
}

static void mainboard_final(void *chip_info)
@@ -241,6 +326,43 @@
return sku;
}

+int fill_mainboard_smbios_type16(unsigned long *current, int *handle)
+{
+ u8 spd_index = get_spd_offset();
+ u8 spd_buffer[CONFIG_DIMM_SPD_SIZE];
+
+ if (read_ddr3_spd_from_cbfs(spd_buffer, spd_index) < 0)
+ return 0;
+
+ struct smbios_type16 *t = (struct smbios_type16 *)*current;
+ int len = sizeof(struct smbios_type16) - 2;
+ memset(t, 0, sizeof(struct smbios_type16));
+
+ t->handle = *handle;
+ t->length = len;
+ t->type = SMBIOS_PHYS_MEMORY_ARRAY;
+ t->use = MEMORY_ARRAY_USE_SYSTEM;
+ t->location = MEMORY_ARRAY_LOCATION_SYSTEM_BOARD;
+ t->maximum_capacity = 4 * 1024 * 1024; // 4GB (in kB) due to board design
+ t->extended_maximum_capacity = 0;
+ t->memory_error_information_handle = 0xFFFE;
+ t->number_of_memory_devices = 1; // only 1 device soldered down to 1 channel
+
+ switch(spd_buffer[3]){
+ case 0x08:
+ t->memory_error_correction = MEMORY_ARRAY_ECC_MULTI_BIT;
+ break;
+ case 0x03:
+ t->memory_error_correction = MEMORY_ARRAY_ECC_NONE;
+ break;
+ default:
+ t->memory_error_correction = MEMORY_ARRAY_ECC_UNKNOWN;
+ break;
+ }
+ len += smbios_string_table_len(t->eos);
+ return len;
+}
+
struct chip_operations mainboard_ops = {
.enable_dev = mainboard_enable,
.final = mainboard_final,

To view, visit change 35889. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I24cd5abceabd11a079a8331e4b95cb69af8e94bf
Gerrit-Change-Number: 35889
Gerrit-PatchSet: 1
Gerrit-Owner: Piotr Kleinschmidt <piotr.kleinschmidt@3mdeb.com>
Gerrit-MessageType: newchange