diff --git a/src/include/cbmem.h b/src/include/cbmem.h index f605191b43..8ba0881859 100644 --- a/src/include/cbmem.h +++ b/src/include/cbmem.h @@ -73,6 +73,7 @@ #define CBMEM_ID_SMM_SAVE_SPACE 0x07e9acee #define CBMEM_ID_RAM_OOPS 0x05430095 #define CBMEM_ID_MEMINFO 0x494D454D +#define CBMEM_ID_AMDMCT_MEMINFO 0x494D454E #define CBMEM_ID_SPINTABLE 0x59175917 #define CBMEM_ID_NONE 0x00000000 #define CBMEM_ID_AGESA_RUNTIME 0x41474553 @@ -119,6 +120,7 @@ struct cbmem_id_to_name { { CBMEM_ID_POWER_STATE, "POWER STATE" }, \ { CBMEM_ID_RAM_OOPS, "RAMOOPS " }, \ { CBMEM_ID_MEMINFO, "MEM INFO " }, \ + { CBMEM_ID_AMDMCT_MEMINFO, "AMDMEM INFO" }, \ { CBMEM_ID_SPINTABLE, "SPIN TABLE " }, struct cbmem_entry; diff --git a/src/northbridge/amd/amdfam10/amdfam10.h b/src/northbridge/amd/amdfam10/amdfam10.h index a77d036aa8..238c45f205 100644 --- a/src/northbridge/amd/amdfam10/amdfam10.h +++ b/src/northbridge/amd/amdfam10/amdfam10.h @@ -977,6 +977,7 @@ that are corresponding to 0x01, 0x02, 0x03, 0x05, 0x06, 0x07 #include "raminit.h" +#include "../amdmct/wrappers/mcti.h" #if (CONFIG_DIMM_SUPPORT & 0x000F)==0x0005 /* AMD_FAM10_DDR3 */ #include "../amdmct/mct_ddr3/mct_d.h" #else diff --git a/src/northbridge/amd/amdfam10/amdfam10_util.c b/src/northbridge/amd/amdfam10/amdfam10_util.c index 2726b280be..621c28f4c8 100644 --- a/src/northbridge/amd/amdfam10/amdfam10_util.c +++ b/src/northbridge/amd/amdfam10/amdfam10_util.c @@ -21,6 +21,7 @@ #include #include +#include #include #include diff --git a/src/northbridge/amd/amdfam10/chip.h b/src/northbridge/amd/amdfam10/chip.h new file mode 100644 index 0000000000..ab853d624b --- /dev/null +++ b/src/northbridge/amd/amdfam10/chip.h @@ -0,0 +1,29 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015 Timothy Pearson , Raptor Engineering + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _AMD_FAM10_CHIP_H_ +#define _AMD_FAM10_CHIP_H_ + +#include + +struct northbridge_amd_amdfam10_config { + uint64_t maximum_memory_capacity; +}; + +#endif /* _AMD_FAM10_CHIP_H_ */ \ No newline at end of file diff --git a/src/northbridge/amd/amdmct/mct/mct_d.c b/src/northbridge/amd/amdmct/mct/mct_d.c index bf832dad81..64cb1bcf21 100644 --- a/src/northbridge/amd/amdmct/mct/mct_d.c +++ b/src/northbridge/amd/amdmct/mct/mct_d.c @@ -2122,7 +2122,7 @@ static u8 DIMMPresence_D(struct MCTStatStruc *pMCTstat, * DATABload=number of ranks on the "B" bus slots. */ - u16 i, j; + u16 i, j, k; u8 smbaddr, Index; u16 Checksum; u8 SPDCtrl; @@ -2183,10 +2183,34 @@ static u8 DIMMPresence_D(struct MCTStatStruc *pMCTstat, pDCTstat->DIMMValid |= 1 << i; } } + /* Get module information for SMBIOS */ + if (pDCTstat->DIMMValid & (1 << i)) { + pDCTstat->DimmManufacturerID[i] = 0; + for (k = 0; k < 8; k++) + pDCTstat->DimmManufacturerID[i] |= ((uint64_t)mctRead_SPD(smbaddr, SPD_MANID_START + k)) << (k * 8); + for (k = 0; k < SPD_PARTN_LENGTH; k++) + pDCTstat->DimmPartNumber[i][k] = mctRead_SPD(smbaddr, SPD_PARTN_START + k); + pDCTstat->DimmRevisionNumber[i] = 0; + for (k = 0; k < 2; k++) + pDCTstat->DimmRevisionNumber[i] |= ((uint16_t)mctRead_SPD(smbaddr, SPD_REVNO_START + k)) << (k * 8); + pDCTstat->DimmSerialNumber[i] = 0; + for (k = 0; k < 4; k++) + pDCTstat->DimmSerialNumber[i] |= ((uint32_t)mctRead_SPD(smbaddr, SPD_SERIAL_START + k)) << (k * 8); + pDCTstat->DimmRows[i] = mctRead_SPD(smbaddr, SPD_ROWSZ) & 0xf; + pDCTstat->DimmCols[i] = mctRead_SPD(smbaddr, SPD_COLSZ) & 0xf; + pDCTstat->DimmRanks[i] = (mctRead_SPD(smbaddr, SPD_DMBANKS) & 0x7) + 1; + pDCTstat->DimmBanks[i] = mctRead_SPD(smbaddr, SPD_LBANKS); + pDCTstat->DimmWidth[i] = mctRead_SPD(smbaddr, SPD_DEVWIDTH); + } /* Check module type */ byte = mctRead_SPD(smbaddr, SPD_DIMMTYPE); - if (byte & JED_REGADCMSK) + if (byte & JED_REGADCMSK) { RegDIMMPresent |= 1 << i; + pDCTstat->DimmRegistered[i] = 1; + } + else { + pDCTstat->DimmRegistered[i] = 0; + } /* Check ECC capable */ byte = mctRead_SPD(smbaddr, SPD_EDCTYPE); if (byte & JED_ECC) { diff --git a/src/northbridge/amd/amdmct/mct/mct_d.h b/src/northbridge/amd/amdmct/mct/mct_d.h index 0c6df6c25e..a1786965d3 100644 --- a/src/northbridge/amd/amdmct/mct/mct_d.h +++ b/src/northbridge/amd/amdmct/mct/mct_d.h @@ -1,6 +1,7 @@ /* * This file is part of the coreboot project. * + * Copyright (C) 2015 Timothy Pearson , Raptor Engineering * Copyright (C) 2007-2008 Advanced Micro Devices, Inc. * * This program is free software; you can redistribute it and/or modify @@ -231,10 +232,17 @@ #define SPD_TRC 41 #define SPD_TRFC 42 +#define SPD_MANID_START 64 +#define SPD_PARTN_START 73 +#define SPD_PARTN_LENGTH 18 +#define SPD_REVNO_START 91 + #define SPD_MANDATEYR 93 /*Module Manufacturing Year (BCD)*/ #define SPD_MANDATEWK 94 /*Module Manufacturing Week (BCD)*/ +#define SPD_SERIAL_START 95 + /*----------------------------- Jedec DDR II related equates -----------------------------*/ @@ -512,6 +520,18 @@ struct DCTStatStruc { /* A per Node structure*/ u32 dev_map; u32 dev_dct; u32 dev_nbmisc; + + uint8_t DimmRows[MAX_DIMMS_SUPPORTED]; + uint8_t DimmCols[MAX_DIMMS_SUPPORTED]; + uint8_t DimmRanks[MAX_DIMMS_SUPPORTED]; + uint8_t DimmBanks[MAX_DIMMS_SUPPORTED]; + uint8_t DimmWidth[MAX_DIMMS_SUPPORTED]; + uint8_t DimmRegistered[MAX_DIMMS_SUPPORTED]; + + uint64_t DimmManufacturerID[MAX_DIMMS_SUPPORTED]; + char DimmPartNumber[MAX_DIMMS_SUPPORTED][SPD_PARTN_LENGTH]; + uint16_t DimmRevisionNumber[MAX_DIMMS_SUPPORTED]; + uint32_t DimmSerialNumber[MAX_DIMMS_SUPPORTED]; } __attribute__((packed)); /*=============================================================================== @@ -666,6 +686,15 @@ struct DCTStatStruc { /* A per Node structure*/ xx0b = disable yy1b = enable with DctSelIntLvAddr set to yyb */ +/*=============================================================================== + CBMEM storage +===============================================================================*/ +struct amdmct_memory_info { + struct MCTStatStruc mct_stat; + struct DCTStatStruc dct_stat[MAX_NODES_SUPPORTED]; + uint16_t ecc_enabled; + uint16_t ecc_scrub_rate; +} __attribute__((packed)); u32 Get_NB32(u32 dev, u32 reg); void Set_NB32(u32 dev, u32 reg, u32 val); diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c index 770b663fe9..0f4dd43642 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c @@ -1,6 +1,7 @@ /* * This file is part of the coreboot project. * + * Copyright (C) 2015 Timothy Pearson , Raptor Engineering * Copyright (C) 2010 Advanced Micro Devices, Inc. * * This program is free software; you can redistribute it and/or modify @@ -2030,7 +2031,7 @@ static u8 DIMMPresence_D(struct MCTStatStruc *pMCTstat, * DATAAload=number of ranks on the "A" bus slots. * DATABload=number of ranks on the "B" bus slots. */ - u16 i, j; + u16 i, j, k; u8 smbaddr; u8 SPDCtrl; u16 RegDIMMPresent, MaxDimms; @@ -2077,10 +2078,34 @@ static u8 DIMMPresence_D(struct MCTStatStruc *pMCTstat, pDCTstat->DIMMValid |= 1 << i; } } + /* Get module information for SMBIOS */ + if (pDCTstat->DIMMValid & (1 << i)) { + pDCTstat->DimmManufacturerID[i] = 0; + for (k = 0; k < 8; k++) + pDCTstat->DimmManufacturerID[i] |= ((uint64_t)mctRead_SPD(smbaddr, SPD_MANID_START + k)) << (k * 8); + for (k = 0; k < SPD_PARTN_LENGTH; k++) + pDCTstat->DimmPartNumber[i][k] = mctRead_SPD(smbaddr, SPD_PARTN_START + k); + pDCTstat->DimmRevisionNumber[i] = 0; + for (k = 0; k < 2; k++) + pDCTstat->DimmRevisionNumber[i] |= ((uint16_t)mctRead_SPD(smbaddr, SPD_REVNO_START + k)) << (k * 8); + pDCTstat->DimmSerialNumber[i] = 0; + for (k = 0; k < 4; k++) + pDCTstat->DimmSerialNumber[i] |= ((uint32_t)mctRead_SPD(smbaddr, SPD_SERIAL_START + k)) << (k * 8); + pDCTstat->DimmRows[i] = (mctRead_SPD(smbaddr, SPD_Addressing) & 0x38) >> 3; + pDCTstat->DimmCols[i] = mctRead_SPD(smbaddr, SPD_Addressing) & 0x7; + pDCTstat->DimmRanks[i] = ((mctRead_SPD(smbaddr, SPD_Organization) & 0x38) >> 3) + 1; + pDCTstat->DimmBanks[i] = 1ULL << (((mctRead_SPD(smbaddr, SPD_Density) & 0x70) >> 4) + 3); + pDCTstat->DimmWidth[i] = 1ULL << ((mctRead_SPD(smbaddr, SPD_BusWidth) & 0x7) + 3); + } /* Check module type */ byte = mctRead_SPD(smbaddr, SPD_DIMMTYPE) & 0x7; - if (byte == JED_RDIMM || byte == JED_MiniRDIMM) + if (byte == JED_RDIMM || byte == JED_MiniRDIMM) { RegDIMMPresent |= 1 << i; + pDCTstat->DimmRegistered[i] = 1; + } + else { + pDCTstat->DimmRegistered[i] = 0; + } /* Check ECC capable */ byte = mctRead_SPD(smbaddr, SPD_BusWidth); if (byte & JED_ECC) { diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h index 8e73afe509..0b1d48fcc3 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h +++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h @@ -1,6 +1,7 @@ /* * This file is part of the coreboot project. * + * Copyright (C) 2015 Timothy Pearson , Raptor Engineering * Copyright (C) 2010 Advanced Micro Devices, Inc. * * This program is free software; you can redistribute it and/or modify @@ -262,6 +263,12 @@ #define SPD_MANDATEWK 94 /*Module Manufacturing Week (BCD)*/ +#define SPD_MANID_START 117 +#define SPD_SERIAL_START 122 +#define SPD_PARTN_START 128 +#define SPD_PARTN_LENGTH 18 +#define SPD_REVNO_START 146 + /*----------------------------- Jedec DDR II related equates -----------------------------*/ @@ -575,6 +582,18 @@ struct DCTStatStruc { /* A per Node structure*/ struct _sMCTStruct s_C_MCTPtr; struct _sDCTStruct s_C_DCTPtr[2]; /* struct _sDCTStruct s_C_DCT1Ptr[8]; */ + + uint8_t DimmRows[MAX_DIMMS_SUPPORTED]; + uint8_t DimmCols[MAX_DIMMS_SUPPORTED]; + uint8_t DimmRanks[MAX_DIMMS_SUPPORTED]; + uint8_t DimmBanks[MAX_DIMMS_SUPPORTED]; + uint8_t DimmWidth[MAX_DIMMS_SUPPORTED]; + uint8_t DimmRegistered[MAX_DIMMS_SUPPORTED]; + + uint64_t DimmManufacturerID[MAX_DIMMS_SUPPORTED]; + char DimmPartNumber[MAX_DIMMS_SUPPORTED][SPD_PARTN_LENGTH]; + uint16_t DimmRevisionNumber[MAX_DIMMS_SUPPORTED]; + uint32_t DimmSerialNumber[MAX_DIMMS_SUPPORTED]; } __attribute__((packed)); /*=============================================================================== @@ -727,6 +746,15 @@ struct DCTStatStruc { /* A per Node structure*/ xx0b = disable yy1b = enable with DctSelIntLvAddr set to yyb */ +/*=============================================================================== + CBMEM storage +===============================================================================*/ +struct amdmct_memory_info { + struct MCTStatStruc mct_stat; + struct DCTStatStruc dct_stat[MAX_NODES_SUPPORTED]; + uint16_t ecc_enabled; + uint16_t ecc_scrub_rate; +} __attribute__((packed)); u32 Get_NB32(u32 dev, u32 reg); void Set_NB32(u32 dev, u32 reg, u32 val);