From 196e9c002122d3469ab486d2f40af1e66dcdf067 Mon Sep 17 00:00:00 2001 From: Rob Barnes Date: Wed, 26 Aug 2020 12:47:27 -0600 Subject: util/spd_tools: Remove intel subfolder Move ddr4 and lp4x to spd_tools root folder. The tool now applies to non intel platforms. BUG=b:162939176 TEST=Run tool Signed-off-by: Rob Barnes Change-Id: I0941ea036d760ee27eb34f259f4506a4b7584bee Reviewed-on: https://review.coreboot.org/c/coreboot/+/44844 Reviewed-by: Furquan Shaikh Reviewed-by: Nick Vaccaro Tested-by: build bot (Jenkins) --- util/spd_tools/intel/ddr4/gen_spd.go | 1386 ---------------------------------- 1 file changed, 1386 deletions(-) delete mode 100644 util/spd_tools/intel/ddr4/gen_spd.go (limited to 'util/spd_tools/intel/ddr4/gen_spd.go') diff --git a/util/spd_tools/intel/ddr4/gen_spd.go b/util/spd_tools/intel/ddr4/gen_spd.go deleted file mode 100644 index 5adadc962a..0000000000 --- a/util/spd_tools/intel/ddr4/gen_spd.go +++ /dev/null @@ -1,1386 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -package main - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "log" - "os" - "path/filepath" - "reflect" - "strconv" - "strings" -) - -/* - * This program generates de-duplicated SPD files for DDR4 memory using the global memory - * part list provided in CSV format. In addition to that, it also generates SPD manifest in CSV - * format that contains entries of type (DRAM part name, SPD file name) which provides the SPD - * file name used by a given DRAM part. - * - * It takes as input: - * Pointer to directory where the generated SPD files will be placed. - * JSON file containing a list of memory parts with their attributes as per datasheet. - */ -const ( - SPDManifestFileName = "spd_manifest.generated.txt" - - PlatformTGL = 0 -) - -var platformMap = map[string]int { - "TGL": PlatformTGL, -} - -var currPlatform int - -type memAttributes struct { - /* Primary attributes - must be provided by JSON file for each part */ - SpeedMTps int - CL_nRCD_nRP int - CapacityPerDieGb int - DiesPerPackage int - DeviceBusWidth int - RanksPerPackage int - - /* - * All the following parameters are optional and required only if the part requires - * special parameters as per the datasheet. - */ - /* Timing parameters */ - TAAMinPs int - TRCDMinPs int - TRPMinPs int - TRASMinPs int - TRCMinPs int - TCKMinPs int - TCKMaxPs int - TRFC1MinPs int - TRFC2MinPs int - TRFC4MinPs int - TFAWMinPs int - TRRDLMinPs int - TRRDSMinPs int - TCCDLMinPs int - TWRMinPs int - TWTRLMinPs int - TWTRSMinPs int - - /* CAS */ - CASLatencies string - CASFirstByte byte - CASSecondByte byte - CASThirdByte byte - CASFourthByte byte -} - -/* This encodes the density in Gb to SPD low nibble value as per JESD 4.1.2.L-5 R29 */ -var densityGbToSPDEncoding = map[int]byte { - 2: 0x3, - 4: 0x4, - 8: 0x5, - 16: 0x6, -} - -/* - * Tables 4 thru Table 7 from JESD79-4C. - * Maps density per die to row-column encoding for a device with x8/x16 - * physical channel. - */ -var densityGbx8x16DieCapacityToRowColumnEncoding = map[int]byte { - 2: 0x11, /* 14 rows, 10 columns */ - 4: 0x19, /* 15 rows, 10 columns */ - 8: 0x21, /* 16 rows, 10 columns */ - 16: 0x29, /* 17 rows, 10 columns */ -} - -/* - * Tables 169 & 170 in the JESD79-4C spec - * Maps die density to refresh timings. This is the same for x8 and x16 - * devices. - */ - -/* maps die density to rcf1 timing in pico seconds */ -var tRFC1Encoding = map[int]int { - 2: 160000, - 4: 260000, - 8: 350000, - 16: 550000, -} - -/* maps die density to rcf2 timing in pico seconds */ -var tRFC2Encoding = map[int]int { - 2: 110000, - 4: 160000, - 8: 260000, - 16: 350000, -} - -/* maps die density to rcf4 timing in pico seconds */ -var tRFC4Encoding = map[int]int { - 2: 90000, - 4: 110000, - 8: 160000, - 16: 260000, -} - -func getTRCMinPs(memAttribs *memAttributes) int { - return memAttribs.TAAMinPs + memAttribs.TRASMinPs -} - -func getDefaultTCKMinPs(memAttribs *memAttributes) int { - /* value 2000000 = 2 * 1000000, where 1000000 is to convert mS to pS */ - return 2000000 / memAttribs.SpeedMTps -} - -type speedBinAttributes struct { - TRASMinPs int - TCKMaxPs int -} - -var speedBinToSPDEncoding = map[int]speedBinAttributes { - 1600: { - TRASMinPs: 35000, - TCKMaxPs: 1500, - }, - 1866: { - TRASMinPs: 34000, - TCKMaxPs: 1250, - }, - 2133: { - TRASMinPs: 33000, - TCKMaxPs: 1071, - }, - 2400: { - TRASMinPs: 32000, - TCKMaxPs: 937, - }, - 2666: { - TRASMinPs: 32000, - TCKMaxPs: 833, - }, - 2933: { - TRASMinPs: 32000, - TCKMaxPs: 750, - }, - 3200: { - TRASMinPs: 32000, - TCKMaxPs: 682, - }, -} - -func getBankGroups(memAttribs *memAttributes) byte { - var bg byte - - switch memAttribs.DeviceBusWidth { - case 8: - bg = 4 - case 16: - if memAttribs.DiesPerPackage == 1 { - bg = 2 /* x16 SDP has 2 bank groups */ - } else { - bg = 4 /* x16 DDP has 4 bank groups */ - } - } - - return bg -} - -func encodeBankGroups(bg byte) byte { - var val byte - - switch bg { - case 2: - val = 1 - case 4: - val = 2 - } - - return val << 6 -} - -func encodeDensityBanks(memAttribs *memAttributes) byte { - var b byte - - b = densityGbToSPDEncoding[memAttribs.CapacityPerDieGb] - b |= encodeBankGroups(getBankGroups(memAttribs)) - /* No need to encode banksPerGroup.it's always 4 ([4:5] = 0) */ - - return b -} - -func encodeSdramAddressing(memAttribs *memAttributes) byte { - var b byte - - b = densityGbx8x16DieCapacityToRowColumnEncoding[memAttribs.CapacityPerDieGb] - - return b -} - -func encodePackageDeviceType(dies int) byte { - var b byte - - if dies > 1 { - /* If more than one die, then this is a non-monolithic device. */ - b = 1 - } else { - /* If only single die, then this is a monolithic device. */ - b = 0 - } - - return b << 7 -} - -func encodeSignalLoadingFromDieCount(dies int) byte { - var loading byte - - /* - * If die count = 1, signal loading = "not specified" = 0 - * If die count > 1, signal loading = "multi" = 2 - */ - if dies == 1 { - loading = 0 - } else { - loading = 1 - } - - return loading -} - -func encodeDiesPerPackage(dies int) byte { - var b byte - - b = encodePackageDeviceType(dies) /* Monolithic / Non-monolithic device */ - b |= (byte(dies) - 1) << 4 - - return b -} - -func encodePackageType(memAttribs *memAttributes) byte { - var b byte - - b = encodeDiesPerPackage(memAttribs.DiesPerPackage) - b |= encodeSignalLoadingFromDieCount(memAttribs.DiesPerPackage) - - return b -} - -func encodeDataWidth(bitWidthPerDevice int) byte { - var width byte - - switch bitWidthPerDevice { - case 8: - width = 1 - case 16: - width = 2 - } - - return width -} - -func encodeRanks(ranks int) byte { - var b byte - - b = byte(ranks - 1) - - return b << 3 -} - -func encodeModuleOrganization(memAttribs *memAttributes) byte { - var b byte - - b = encodeDataWidth(memAttribs.DeviceBusWidth) - b |= encodeRanks(memAttribs.RanksPerPackage) - - return b -} - -func encodeTCKMin(memAttribs *memAttributes) byte { - return convPsToMtbByte(memAttribs.TCKMinPs) -} - -func encodeTCKMinFineOffset(memAttribs *memAttributes) byte { - return convPsToFtbByte(memAttribs.TCKMinPs) -} - -func encodeTCKMax(memAttribs *memAttributes) byte { - return convPsToMtbByte(memAttribs.TCKMaxPs) -} - -func encodeTCKMaxFineOffset(memAttribs *memAttributes) byte { - return convPsToFtbByte(memAttribs.TCKMaxPs) -} - -func divRoundUp(dividend int, divisor int) int { - return (dividend + divisor - 1) / divisor -} - -func convNsToPs(timeNs int) int { - return timeNs * 1000 -} - -func convMtbToPs(mtb int) int { - return mtb * 125 -} - -func convPsToMtb(timePs int) int { - return divRoundUp(timePs, 125) -} - -func convPsToMtbByte(timePs int) byte { - return byte(convPsToMtb(timePs) & 0xff) -} - -func convPsToFtbByte(timePs int) byte { - mtb := convPsToMtb(timePs) - ftb := timePs - convMtbToPs(mtb) - - return byte(ftb) -} - -func encodeTAAMin(memAttribs *memAttributes) byte { - return convPsToMtbByte(memAttribs.TAAMinPs) -} - -func encodeTAAMinFineOffset(memAttribs *memAttributes) byte { - return convPsToFtbByte(memAttribs.TAAMinPs) -} - -func encodeTRCDMin(memAttribs *memAttributes) byte { - return convPsToMtbByte(memAttribs.TRCDMinPs) -} - -func encodeTRCDMinFineOffset(memAttribs *memAttributes) byte { - return convPsToFtbByte(memAttribs.TRCDMinPs) -} - -func encodeTRPMin(memAttribs *memAttributes) byte { - return convPsToMtbByte(memAttribs.TRPMinPs) -} - -func encodeTRCMinFineOffset(memAttribs *memAttributes) byte { - return convPsToFtbByte(memAttribs.TRCMinPs) -} - -func encodeTRPMinFineOffset(memAttribs *memAttributes) byte { - return convPsToFtbByte(memAttribs.TRPMinPs) -} - -func encodeTRASRCMinMSNs(memAttribs *memAttributes) byte { - var b byte - - b = byte((convPsToMtb(memAttribs.TRASMinPs) >> 4) & 0xf0) - b |= byte((convPsToMtb(memAttribs.TRCMinPs) >> 8) & 0x0f) - - return b -} - -func encodeTRASMinLsb(memAttribs *memAttributes) byte { - return byte(convPsToMtb(memAttribs.TRASMinPs) & 0xff) -} - -func encodeTRCMinLsb(memAttribs *memAttributes) byte { - return byte(convPsToMtb(memAttribs.TRCMinPs) & 0xff) -} - -var pageSizefromBusWidthEncoding = map[int]int { - 8: 1, - 16: 2, -} - -/* - * Per Table 69 & Table 70 of Jedec JESD79-4C - * tFAW timing is based on : - * Speed bin and page size - */ -func getTFAWMinPs(memAttribs *memAttributes) int { - var tFAWFixed int - - if pageSizefromBusWidthEncoding[memAttribs.DeviceBusWidth] == 1 { - switch memAttribs.SpeedMTps { - case 1600: - tFAWFixed = 25000 - case 1866: - tFAWFixed = 23000 - default: - tFAWFixed = 21000 - } - } else if pageSizefromBusWidthEncoding[memAttribs.DeviceBusWidth] == 2 { - switch memAttribs.SpeedMTps { - case 1600: - tFAWFixed = 35000 - default: - tFAWFixed = 30000 - } - } - - return tFAWFixed -} - -/* Update settings based on data sheet (json) supplied memory attributes */ - -func updateTFAWMin(memAttribs *memAttributes) { - var tFAWFromTck int - - if memAttribs.TFAWMinPs == 0 { - memAttribs.TFAWMinPs = getTFAWMinPs(memAttribs) - } - - switch pageSizefromBusWidthEncoding[memAttribs.DeviceBusWidth] { - case 1: - tFAWFromTck = 20 * memAttribs.TCKMinPs - case 2: - tFAWFromTck = 28 * memAttribs.TCKMinPs - } - - if memAttribs.TFAWMinPs < tFAWFromTck { - memAttribs.TFAWMinPs = tFAWFromTck - } -} - -func updateTRFC1Min(memAttribs *memAttributes) { - if memAttribs.TRFC1MinPs == 0 { - memAttribs.TRFC1MinPs = tRFC1Encoding[memAttribs.CapacityPerDieGb] - } -} - -func updateTRFC2Min(memAttribs *memAttributes) { - if memAttribs.TRFC2MinPs == 0 { - memAttribs.TRFC2MinPs = tRFC2Encoding[memAttribs.CapacityPerDieGb] - } -} - -func updateTRFC4Min(memAttribs *memAttributes) { - if memAttribs.TRFC4MinPs == 0 { - memAttribs.TRFC4MinPs = tRFC4Encoding[memAttribs.CapacityPerDieGb] - } -} - -func getTRRDLMinPs(memAttribs *memAttributes) int { - var tRRDLFixed int - - /* - * Per JESD79-4C Tables 169 & 170, tRRD_L is based on : - * Speed bin and page size - */ - switch pageSizefromBusWidthEncoding[memAttribs.DeviceBusWidth] { - case 1: - switch memAttribs.SpeedMTps { - case 1600: - tRRDLFixed = 6000 - default: - tRRDLFixed = 5300 - } - case 2: - switch memAttribs.SpeedMTps { - case 1600: - tRRDLFixed = 7500 - default: - tRRDLFixed = 6400 - } - } - - return tRRDLFixed -} - -func updateTRRDLMin(memAttribs *memAttributes) { - var tRRDLFromTck int - - if memAttribs.TRRDLMinPs == 0 { - memAttribs.TRRDLMinPs= getTRRDLMinPs(memAttribs) - } - - tRRDLFromTck = 4 * memAttribs.TCKMinPs - - if memAttribs.TRRDLMinPs < tRRDLFromTck { - memAttribs.TRRDLMinPs = tRRDLFromTck - } -} - -var speedToTRRDSMinPsOneKPageSize = map[int]int { - 1600: 5000, - 1866: 4200, - 2133: 3700, - 2400: 3300, - 2666: 3000, - 2933: 2700, - 3200: 2500, -} - -var speedToTRRDSMinPsTwoKPageSize = map[int]int { - 1600: 6000, - 1866: 5300, - 2133: 5300, - 2400: 5300, - 2666: 5300, - 2933: 5300, - 3200: 5300, -} - -func getTRRDSMinPs(memAttribs *memAttributes) int { - var tRRDFixed int - - switch pageSizefromBusWidthEncoding[memAttribs.DeviceBusWidth] { - case 1: - tRRDFixed = speedToTRRDSMinPsOneKPageSize[memAttribs.SpeedMTps] - case 2: - tRRDFixed = speedToTRRDSMinPsTwoKPageSize[memAttribs.SpeedMTps] - } - - return tRRDFixed -} - -func updateTRRDSMin(memAttribs *memAttributes) { - var tRRDFromTck int - - if memAttribs.TRRDSMinPs == 0 { - memAttribs.TRRDSMinPs = getTRRDSMinPs(memAttribs) - } - - tRRDFromTck = 4 * memAttribs.TCKMinPs - - if memAttribs.TRRDSMinPs < tRRDFromTck { - memAttribs.TRRDSMinPs = tRRDFromTck - } -} - -/* - * Per JESD79-4C Tables 169 and 170, - * tCCD_L is based on : - * Speed Bin - */ -func getTCCDLMinPs(memAttribs *memAttributes) int { - var tCCDLFixed int - - switch memAttribs.SpeedMTps { - case 1600: - tCCDLFixed = 6250 - case 1866: - tCCDLFixed = 5355 - case 2133: - tCCDLFixed = 5355 - default: - tCCDLFixed = 5000 - } - - return tCCDLFixed -} - -func updateTCCDLMin(memAttribs *memAttributes) { - var tCCDLFromTck int - - if memAttribs.TCCDLMinPs == 0 { - memAttribs.TCCDLMinPs = getTCCDLMinPs(memAttribs) - } - - tCCDLFromTck = 5 * memAttribs.TCKMinPs - - if memAttribs.TCCDLMinPs < tCCDLFromTck { - memAttribs.TCCDLMinPs = tCCDLFromTck - } -} - -func encodeTRFC1MinLsb(memAttribs *memAttributes) byte { - var mtb int - - mtb = convPsToMtb(memAttribs.TRFC1MinPs) - - return byte(mtb & 0xff) -} - -func encodeTRFC1MinMsb(memAttribs *memAttributes) byte { - var mtb int - - mtb = convPsToMtb(memAttribs.TRFC1MinPs) - - return byte((mtb >> 8) & 0xff) -} - -func encodeTRFC2MinLsb(memAttribs *memAttributes) byte { - var mtb int - - mtb = convPsToMtb(memAttribs.TRFC2MinPs) - - return byte(mtb & 0xff) -} - -func encodeTRFC2MinMsb(memAttribs *memAttributes) byte { - var mtb int - - mtb = convPsToMtb(memAttribs.TRFC2MinPs) - - return byte((mtb >> 8) & 0xff) -} - -func encodeTRFC4MinLsb(memAttribs *memAttributes) byte { - var mtb int - - mtb = convPsToMtb(memAttribs.TRFC4MinPs) - - return byte(mtb & 0xff) -} - -func encodeTRFC4MinMsb(memAttribs *memAttributes) byte { - var mtb int - - mtb = convPsToMtb(memAttribs.TRFC4MinPs) - - return byte((mtb >> 8) & 0xff) -} - -func encodeTFAWMinMSN(memAttribs *memAttributes) byte { - var mtb int - - mtb = convPsToMtb(memAttribs.TFAWMinPs) - - return byte((mtb >> 8) & 0x0f) -} - -func encodeTFAWMinLsb(memAttribs *memAttributes) byte { - var mtb int - - mtb = convPsToMtb(memAttribs.TFAWMinPs) - - return byte(mtb & 0xff) -} - -func encodeCASFirstByte(memAttribs *memAttributes) byte { - return memAttribs.CASFirstByte -} - -func encodeCASSecondByte(memAttribs *memAttributes) byte { - return memAttribs.CASSecondByte -} - -func encodeCASThirdByte(memAttribs *memAttributes) byte { - return memAttribs.CASThirdByte -} - -func encodeCASFourthByte(memAttribs *memAttributes) byte { - return memAttribs.CASFourthByte -} - -func encodeTRRDSMin(memAttribs *memAttributes) byte { - return convPsToMtbByte(memAttribs.TRRDSMinPs) -} - -func encodeTRRDSMinFineOffset(memAttribs *memAttributes) byte { - return convPsToFtbByte(memAttribs.TRRDSMinPs) -} - -func encodeTRRDLMin(memAttribs *memAttributes) byte { - return convPsToMtbByte(memAttribs.TRRDLMinPs) -} - -func encodeTRRDLMinFineOffset(memAttribs *memAttributes) byte { - return convPsToFtbByte(memAttribs.TRRDLMinPs) -} - -func encodeTCCDLMin(memAttribs *memAttributes) byte { - return convPsToMtbByte(memAttribs.TCCDLMinPs) -} - -func encodeTCCDLMinFineOffset(memAttribs *memAttributes) byte { - return convPsToFtbByte(memAttribs.TCCDLMinPs) -} - -func encodeTWRMinMSN(memAttribs *memAttributes) byte { - return byte((convPsToMtb(TimingValueTWRMinPs) >> 8) & 0x0f) -} - -func encodeTWRMinLsb(memAttribs *memAttributes) byte { - return byte(convPsToMtb(TimingValueTWRMinPs) & 0xff) -} - -func encodeTWTRMinMSNs(memAttribs *memAttributes) byte { - var b byte - - b = byte((convPsToMtb(memAttribs.TWTRLMinPs) >> 4) & 0xf0) - b |= byte((convPsToMtb(memAttribs.TWTRSMinPs) >> 8) & 0x0f) - - return b -} - -func encodeTWTRSMinLsb(memAttribs *memAttributes) byte { - return byte(convPsToMtb(memAttribs.TWTRSMinPs) & 0xff) -} - -func encodeTWTRLMinLsb(memAttribs *memAttributes) byte { - return byte(convPsToMtb(memAttribs.TWTRLMinPs) & 0xff) -} - -type SPDMemAttribFunc func (*memAttributes) byte -type SPDConvConstFunc func () byte - -type SPDAttribTableEntry struct { - constVal byte - getVal SPDMemAttribFunc -} - -const ( - /* SPD Byte Index */ - SPDIndexSize = 0 - SPDIndexRevision = 1 - SPDIndexMemoryType = 2 - SPDIndexModuleType = 3 - SPDIndexDensityBanks = 4 - SPDIndexAddressing = 5 - SPDIndexPackageType = 6 - SPDIndexOptionalFeatures = 7 - SPDIndexModuleOrganization = 12 - SPDIndexBusWidth = 13 - SPDIndexTimebases = 17 - SPDIndexTCKMin = 18 - SPDIndexTCKMax = 19 - SPDIndexCASFirstByte = 20 - SPDIndexCASSecondByte = 21 - SPDIndexCASThirdByte = 22 - SPDIndexCASFourthByte = 23 - SPDIndexTAAMin = 24 - SPDIndexTRCDMin = 25 - SPDIndexTRPMin = 26 - SPDIndexTRASRCMinMSNs = 27 - SPDIndexTRASMinLsb = 28 - SPDIndexTRCMinLsb = 29 - SPDIndexTRFC1MinLsb = 30 - SPDIndexTRFC1MinMsb = 31 - SPDIndexTRFC2MinLsb = 32 - SPDIndexTRFC2MinMsb = 33 - SPDIndexTRFC4MinLsb = 34 - SPDIndexTRFC4MinMsb = 35 - SPDIndexTFAWMinMSN = 36 - SPDIndexTFAWMinLsb = 37 - SPDIndexTRRDSMin = 38 - SPDIndexTRRDLMin = 39 - SPDIndexTCCDLMin = 40 - SPDIndexTWRMinMSN = 41 - SPDIndexTWRMinLsb = 42 - SPDIndexTWTRMinMSNs = 43 - SPDIndexWTRSMinLsb = 44 - SPDIndexWTRLMinLsb = 45 - SPDIndexTCCDLMinFineOffset = 117 - SPDIndexTRRDLMinFineOffset = 118 - SPDIndexTRRDSMinFineOffset = 119 - SPDIndexTRCMinFineOffset = 120 - SPDIndexTRPMinFineOffset = 121 - SPDIndexTRCDMinFineOffset = 122 - SPDIndexTAAMinFineOffset = 123 - SPDIndexTCKMaxFineOffset = 124 - SPDIndexTCKMinFineOffset = 125 - SPDIndexManufacturerPartNumberStartByte = 329 - SPDIndexManufacturerPartNumberEndByte = 348 - - /* SPD Byte Value */ - - /* - * From JEDEC spec: - * 6:4 (Bytes total) = 2 (512 bytes) - * 3:0 (Bytes used) = 3 (384 bytes) - * Set to 0x23 for DDR4. - */ - SPDValueSize = 0x23 - - /* - * From JEDEC spec: Revision 1.1 - * Set to 0x11. - */ - SPDValueRevision = 0x11 - - /* DDR4 memory type = 0x0C */ - SPDValueMemoryType = 0x0C - - /* - * From JEDEC spec: - * Module Type [0:3] : - * 0 = Undefined - * 1 = RDIMM (width = 133.35 mm nom) - * 2 = UDIMM (width = 133.35 mm nom) - * 3 = SO-DIMM (width = 68.60 mm nom) - * 4 = LRDIMM (width = 133.35 mm nom) - * - * DDR4 on TGL uses SO-DIMM type for for both memory down and DIMM config. - * Set to 0x03. - */ - SPDValueModuleType = 0x03 - - /* - * From JEDEC spec: - * 5:4 (Maximum Activate Window) = 00 (8192 * tREFI) - * 3:0 (Maximum Activate Count) = 1000 (Unlimited MAC) - * - * Needs to come from datasheet, but most parts seem to support unlimited MAC. - * MR#24 OP3 - */ - SPDValueOptionalFeatures = 0x08 - - /* - * From JEDEC spec: - * 2:0 Primary Bus Width in Bits = 011 (x64 always) - * Set to 0x03. - */ - SPDValueModuleBusWidth = 0x03 - - /* - * From JEDEC spec: - * 3:2 (MTB) = 00 (0.125ns) - * 1:0 (FTB) = 00 (1ps) - * Set to 0x00. - */ - SPDValueTimebases = 0x00 - - /* CAS fourth byte: All bits are reserved */ - SPDValueCASFourthByte = 0x00 - - /* As per JEDEC spec, unused digits of manufacturer part number are left as blank. */ - SPDValueManufacturerPartNumberBlank = 0x20 - -) - -const ( - /* - * As per Table 75 of Jedec spec 4.1.20-L-5 R29 v103: - * tWRMin = 15nS for all DDR4 Speed Bins - * Set to 15000 pS - */ - TimingValueTWRMinPs = 15000 - - /* - * As per Table 78 of Jedec spec 4.1.20-L-5 R29 v103: - * tWTR_SMin = 2.5nS for all DDR4 Speed Bins - * Set to 2500 pS - */ - TimingValueTWTRSMinPs = 2500 - - /* - * As per Table 80 of Jedec spec 4.1.20-L-5 R29 v103: - * tWTR_LMin = 7.5 nS for all DDR4 Speed Bins - * Set to 7500 pS - */ - TimingValueTWTRLMinPs = 7500 -) - -var SPDAttribTable = map[int]SPDAttribTableEntry { - SPDIndexSize: { constVal: SPDValueSize }, - SPDIndexRevision: { constVal: SPDValueRevision }, - SPDIndexMemoryType: { constVal: SPDValueMemoryType }, - SPDIndexModuleType: { constVal: SPDValueModuleType }, - SPDIndexDensityBanks: { getVal: encodeDensityBanks }, - SPDIndexAddressing: { getVal: encodeSdramAddressing }, - SPDIndexPackageType: { getVal: encodePackageType }, - SPDIndexOptionalFeatures: { constVal: SPDValueOptionalFeatures }, - SPDIndexModuleOrganization: { getVal: encodeModuleOrganization }, - SPDIndexBusWidth: { constVal: SPDValueModuleBusWidth }, - SPDIndexTimebases: { constVal: SPDValueTimebases }, - SPDIndexTCKMin: { getVal: encodeTCKMin }, - SPDIndexTCKMinFineOffset: { getVal: encodeTCKMinFineOffset }, - SPDIndexTCKMax: { getVal: encodeTCKMax }, - SPDIndexTCKMaxFineOffset: { getVal: encodeTCKMaxFineOffset }, - SPDIndexCASFirstByte: { getVal: encodeCASFirstByte }, - SPDIndexCASSecondByte: { getVal: encodeCASSecondByte }, - SPDIndexCASThirdByte: { getVal: encodeCASThirdByte }, - SPDIndexCASFourthByte: { getVal: encodeCASFourthByte }, - SPDIndexTAAMin: { getVal: encodeTAAMin }, - SPDIndexTAAMinFineOffset: { getVal: encodeTAAMinFineOffset }, - SPDIndexTRCDMin: { getVal: encodeTRCDMin }, - SPDIndexTRCDMinFineOffset: { getVal: encodeTRCDMinFineOffset }, - SPDIndexTRPMin: { getVal: encodeTRPMin }, - SPDIndexTRPMinFineOffset: { getVal: encodeTRPMinFineOffset }, - SPDIndexTRASRCMinMSNs: { getVal: encodeTRASRCMinMSNs }, - SPDIndexTRASMinLsb: { getVal: encodeTRASMinLsb }, - SPDIndexTRCMinLsb: { getVal: encodeTRCMinLsb }, - SPDIndexTRCMinFineOffset: { getVal: encodeTRCMinFineOffset }, - SPDIndexTRFC1MinLsb: { getVal: encodeTRFC1MinLsb }, - SPDIndexTRFC1MinMsb: { getVal: encodeTRFC1MinMsb }, - SPDIndexTRFC2MinLsb: { getVal: encodeTRFC2MinLsb }, - SPDIndexTRFC2MinMsb: { getVal: encodeTRFC2MinMsb }, - SPDIndexTRFC4MinLsb: { getVal: encodeTRFC4MinLsb }, - SPDIndexTRFC4MinMsb: { getVal: encodeTRFC4MinMsb }, - SPDIndexTFAWMinMSN: { getVal: encodeTFAWMinMSN }, - SPDIndexTFAWMinLsb: { getVal: encodeTFAWMinLsb }, - SPDIndexTRRDSMin: { getVal: encodeTRRDSMin }, - SPDIndexTRRDSMinFineOffset: { getVal: encodeTRRDSMinFineOffset }, - SPDIndexTRRDLMin: { getVal: encodeTRRDLMin }, - SPDIndexTRRDLMinFineOffset: { getVal: encodeTRRDLMinFineOffset }, - SPDIndexTCCDLMin: { getVal: encodeTCCDLMin }, - SPDIndexTCCDLMinFineOffset: { getVal: encodeTCCDLMinFineOffset }, - SPDIndexTWRMinMSN: { getVal: encodeTWRMinMSN }, - SPDIndexTWRMinLsb: { getVal: encodeTWRMinLsb }, - SPDIndexTWTRMinMSNs: { getVal: encodeTWTRMinMSNs }, - SPDIndexWTRSMinLsb: { getVal: encodeTWTRSMinLsb }, - SPDIndexWTRLMinLsb: { getVal: encodeTWTRLMinLsb }, -} - -type memParts struct { - MemParts []memPart `json:"parts"` -} - -type memPart struct { - Name string - Attribs memAttributes - SPDFileName string -} - -func writeSPDManifest(memParts *memParts, SPDDirName string) error { - var s string - - fmt.Printf("Generating SPD Manifest with following entries:\n") - - for i := 0; i < len(memParts.MemParts); i++ { - fmt.Printf("%-40s %s\n", memParts.MemParts[i].Name, memParts.MemParts[i].SPDFileName) - s += fmt.Sprintf("%s,%s\n", memParts.MemParts[i].Name, memParts.MemParts[i].SPDFileName) - } - - return ioutil.WriteFile(filepath.Join(SPDDirName, SPDManifestFileName), []byte(s), 0644) -} - -func isManufacturerPartNumberByte(index int) bool { - if index >= SPDIndexManufacturerPartNumberStartByte && index <= SPDIndexManufacturerPartNumberEndByte { - return true - } - return false -} - - -func getSPDByte(index int, memAttribs *memAttributes) byte { - e, ok := SPDAttribTable[index] - if ok == false { - if isManufacturerPartNumberByte(index) { - return SPDValueManufacturerPartNumberBlank - } - return 0x00 - } - - if e.getVal != nil { - return e.getVal(memAttribs) - } - - return e.constVal -} - -func createSPD(memAttribs *memAttributes) string { - var s string - - for i := 0; i < 512; i++ { - b := getSPDByte(i, memAttribs) - - if (i + 1) % 16 == 0 { - s += fmt.Sprintf("%02X\n", b) - } else { - s += fmt.Sprintf("%02X ", b) - } - } - - return s -} - -func dedupeMemoryPart(dedupedParts []*memPart, memPart *memPart) bool { - for i := 0; i < len(dedupedParts); i++ { - if reflect.DeepEqual(dedupedParts[i].Attribs, memPart.Attribs) { - memPart.SPDFileName = dedupedParts[i].SPDFileName - return true - } - } - - return false -} - -func generateSPD(memPart *memPart, SPDId int, SPDDirName string) { - s := createSPD(&memPart.Attribs) - memPart.SPDFileName = fmt.Sprintf("ddr4-spd-%d.hex", SPDId) - ioutil.WriteFile(filepath.Join(SPDDirName, memPart.SPDFileName), []byte(s), 0644) -} - -func readMemoryParts(memParts *memParts, memPartsFileName string) error { - databytes, err := ioutil.ReadFile(memPartsFileName) - if err != nil { - return err - } - - return json.Unmarshal(databytes, memParts) -} - -func validateSpeedMTps(speedBin int) error { - if _, ok := speedBinToSPDEncoding[speedBin]; ok == false { - return fmt.Errorf("Incorrect speed bin: DDR4-", speedBin) - } - return nil -} - -func validateCapacityPerDie(capacityPerDieGb int) error { - if _, ok := densityGbToSPDEncoding[capacityPerDieGb]; ok == false { - return fmt.Errorf("Incorrect capacity per die: ", capacityPerDieGb) - } - return nil -} - -func validateDiesPerPackage(dieCount int) error { - if dieCount >= 1 && dieCount <= 2 { - return nil - } - return fmt.Errorf("Incorrect dies per package count: ", dieCount) -} - -func validateDeviceBusWidth(width int) error { - if width != 8 && width != 16 { - return fmt.Errorf("Incorrect device bus width: ", width) - } - return nil -} - -func validateRanksPerPackage(ranks int) error { - if ranks >= 1 && ranks <= 2 { - return nil - } - return fmt.Errorf("Incorrect package ranks: ", ranks) -} - - -func validateCASLatency(CL int) error { - if CL >= 10 && CL <= 24 && CL != 23 { - return nil - } - return fmt.Errorf("Incorrect CAS latency: ", CL) -} - -/* -1) validate memory parts -2) remove any fields that Intel does not care about -*/ - -/* verify the supplied CAS Latencies supported does not match default */ -func verifySupportedCASLatencies(part *memPart) error { - if part.Attribs.CASLatencies == getDefaultCASLatencies(&part.Attribs) { - return fmt.Errorf("CASLatencies for %s already matches default,\nPlease remove CASLatencies override line from the %s part attributes in the global part list and regenerate SPD Manifest", part.Name, part.Name) - } - - return nil -} - -func validateMemoryParts(memParts *memParts) error { - for i := 0; i < len(memParts.MemParts); i++ { - if err := validateSpeedMTps(memParts.MemParts[i].Attribs.SpeedMTps); err != nil { - return err - } - if err := validateCapacityPerDie(memParts.MemParts[i].Attribs.CapacityPerDieGb); err != nil { - return err - } - if err := validateDiesPerPackage(memParts.MemParts[i].Attribs.DiesPerPackage); err != nil { - return err - } - if err := validateDeviceBusWidth(memParts.MemParts[i].Attribs.DeviceBusWidth); err != nil { - return err - } - if err := validateRanksPerPackage(memParts.MemParts[i].Attribs.RanksPerPackage); err != nil { - return err - } - if err := validateCASLatency(memParts.MemParts[i].Attribs.CL_nRCD_nRP); err != nil { - return err - } - /* If CAS Latency was supplied, make sure it doesn't match default value */ - if len(memParts.MemParts[i].Attribs.CASLatencies) != 0 { - if err := verifySupportedCASLatencies(&memParts.MemParts[i]); err != nil { - return err - } - } - } - - return nil -} - -const ( - /* First Byte */ - CAS9 = 1 << 2 - CAS10 = 1 << 3 - CAS11 = 1 << 4 - CAS12 = 1 << 5 - CAS13 = 1 << 6 - CAS14 = 1 << 7 - /* Second Byte */ - CAS15 = 1 << 0 - CAS16 = 1 << 1 - CAS17 = 1 << 2 - CAS18 = 1 << 3 - CAS19 = 1 << 4 - CAS20 = 1 << 5 - CAS21 = 1 << 6 - CAS22 = 1 << 7 - /* Third Byte */ - CAS24 = 1 << 1 -) - -func encodeLatencies(latency int, memAttribs *memAttributes) error { - switch latency { - case 9: - memAttribs.CASFirstByte |= CAS9 - case 10: - memAttribs.CASFirstByte |= CAS10 - case 11: - memAttribs.CASFirstByte |= CAS11 - case 12: - memAttribs.CASFirstByte |= CAS12 - case 13: - memAttribs.CASFirstByte |= CAS13 - case 14: - memAttribs.CASFirstByte |= CAS14 - case 15: - memAttribs.CASSecondByte |= CAS15 - case 16: - memAttribs.CASSecondByte |= CAS16 - case 17: - memAttribs.CASSecondByte |= CAS17 - case 18: - memAttribs.CASSecondByte |= CAS18 - case 19: - memAttribs.CASSecondByte |= CAS19 - case 20: - memAttribs.CASSecondByte |= CAS20 - case 21: - memAttribs.CASSecondByte |= CAS21 - case 22: - memAttribs.CASSecondByte |= CAS22 - case 24: - memAttribs.CASThirdByte |= CAS24 - default: - fmt.Errorf("Incorrect CAS Latency: ", latency) - } - - return nil -} - -/* Default CAS Latencies from Speed Bin tables in JEDS79-4C */ -func getDefaultCASLatencies(memAttribs *memAttributes) string { - var str string - - switch memAttribs.SpeedMTps { - case 1600: - switch memAttribs.CL_nRCD_nRP { - case 10: - str = "9 10 11 12" - case 11: - str = "9 11 12" - case 12: - str = "10 12" - } - case 1866: - switch memAttribs.CL_nRCD_nRP { - case 12: - str = "9 10 12 13 14" - case 13: - str = "9 11 12 13 14" - case 14: - str = "10 12 14" - } - case 2133: - switch memAttribs.CL_nRCD_nRP { - case 14: - str = "9 10 12 14 15 16" - case 15: - str = "9 11 12 13 14 15 16" - case 16: - str = "10 12 14 16" - } - case 2400: - switch memAttribs.CL_nRCD_nRP { - case 15: - str = "9 10 12 14 15 16 17 18" - case 16: - str = "9 11 12 13 14 15 16 17 18" - case 17: - str = "10 11 12 13 14 15 16 17 18" - case 18: - str = "10 12 14 16 18" - } - case 2666: - switch memAttribs.CL_nRCD_nRP { - case 17: - str = "9 10 11 12 13 14 15 16 17 18 19 20" - case 18: - str = "9 10 11 12 13 14 15 16 17 18 19 20" - case 19: - str = "10 11 12 13 14 15 16 17 18 19 20" - case 20: - str = "10 12 14 16 18 20" - } - case 2933: - switch memAttribs.CL_nRCD_nRP { - case 19: - str = "9 10 11 12 13 14 15 16 17 18 19 20 21 22" - case 20: - str = "10 11 12 13 14 15 16 17 18 19 20 21 22" - case 21: - str = "10 11 12 13 14 15 16 17 18 19 20 21 22" - case 22: - str = "10 12 14 16 18 20 22" - } - case 3200: - switch memAttribs.CL_nRCD_nRP { - case 20: - str = "9 10 11 12 13 14 15 16 17 18 19 20 21 22 24" - case 22: - str = "10 11 12 13 14 15 16 17 18 19 20 21 22 24" - case 24: - str = "10 12 14 16 18 20 22 24" - } - } - - return str -} - -func updateCAS(memAttribs *memAttributes) error { - if len(memAttribs.CASLatencies) == 0 { - memAttribs.CASLatencies = getDefaultCASLatencies(memAttribs) - } - - latencies := strings.Fields(memAttribs.CASLatencies) - for i := 0; i < len(latencies); i++ { - latency,err := strconv.Atoi(latencies[i]) - if err != nil { - return fmt.Errorf("Unable to convert latency ", latencies[i]) - } - if err := encodeLatencies(latency, memAttribs); err != nil { - return err - } - } - - return nil -} - -func getTAAMinPs(memAttribs *memAttributes) int { - return (memAttribs.CL_nRCD_nRP * 2000000) / memAttribs.SpeedMTps -} - -func updateTAAMin(memAttribs *memAttributes) { - if memAttribs.TAAMinPs == 0 { - memAttribs.TAAMinPs = getTAAMinPs(memAttribs) - } -} - -func updateTRCDMin(memAttribs *memAttributes) { - /* tRCDmin is same as tAAmin for all cases */ - if memAttribs.TRCDMinPs == 0 { - memAttribs.TRCDMinPs = getTAAMinPs(memAttribs) - } -} - -func updateTRPMin(memAttribs *memAttributes) { - /* tRPmin is same as tAAmin for all cases */ - if memAttribs.TRPMinPs == 0 { - memAttribs.TRPMinPs = getTAAMinPs(memAttribs) - } -} - -func updateTRASMin(memAttribs *memAttributes) { - if memAttribs.TRASMinPs == 0 { - memAttribs.TRASMinPs = speedBinToSPDEncoding[memAttribs.SpeedMTps].TRASMinPs - } -} - - -func updateTRCMin(memAttribs *memAttributes) { - if memAttribs.TRCMinPs == 0 { - memAttribs.TRCMinPs = getTRCMinPs(memAttribs) - } -} - -func updateTCK(memAttribs *memAttributes) { - if memAttribs.TCKMinPs == 0 { - memAttribs.TCKMinPs = getDefaultTCKMinPs(memAttribs) - } - if memAttribs.TCKMaxPs == 0 { - memAttribs.TCKMaxPs = speedBinToSPDEncoding[memAttribs.SpeedMTps].TCKMaxPs - } -} - -func updateTWRMin(memAttribs *memAttributes) { - if memAttribs.TWRMinPs == 0 { - memAttribs.TWRMinPs = TimingValueTWRMinPs - } -} - -func updateTWTRMin(memAttribs *memAttributes) { - if memAttribs.TWTRLMinPs == 0 { - memAttribs.TWTRLMinPs = TimingValueTWTRLMinPs - } - if memAttribs.TWTRSMinPs == 0 { - memAttribs.TWTRSMinPs = TimingValueTWTRSMinPs - } -} - -func updateMemoryAttributes(memAttribs *memAttributes) { - updateTCK(memAttribs) - updateTAAMin(memAttribs) - updateTRCDMin(memAttribs) - updateTRPMin(memAttribs) - updateTRASMin(memAttribs) - updateTRCMin(memAttribs) - updateTWRMin(memAttribs) - updateTWTRMin(memAttribs) - updateCAS(memAttribs) - updateTRFC1Min(memAttribs) - updateTRFC2Min(memAttribs) - updateTRFC4Min(memAttribs) - updateTCCDLMin(memAttribs) - updateTRRDSMin(memAttribs) - updateTRRDLMin(memAttribs) - updateTFAWMin(memAttribs) -} - -func isPlatformSupported(platform string) error { - var ok bool - - currPlatform, ok = platformMap[platform] - if ok == false { - return fmt.Errorf("Unsupported platform: ", platform) - } - - return nil -} - -func usage() { - fmt.Printf("\nUsage: %s \n\n", os.Args[0]) - fmt.Printf(" where,\n") - fmt.Printf(" spd_dir = Directory path containing SPD files and manifest generated by gen_spd.go\n") - fmt.Printf(" mem_parts_list_json = JSON File containing list of memory parts and attributes\n") - fmt.Printf(" platform = SoC Platform for which the SPDs are being generated\n\n\n") -} - -func main() { - if len(os.Args) != 4 { - usage() - log.Fatal("Incorrect number of arguments") - } - - var memParts memParts - var dedupedParts []*memPart - - SPDDir, GlobalMemPartsFile, Platform := os.Args[1], os.Args[2], strings.ToUpper(os.Args[3]) - - if err := isPlatformSupported(Platform); err != nil { - log.Fatal(err) - } - - if err := readMemoryParts(&memParts, GlobalMemPartsFile); err != nil { - log.Fatal(err) - } - - if err := validateMemoryParts(&memParts); err != nil { - log.Fatal(err) - } - - SPDId := 1 - - for i := 0; i < len(memParts.MemParts); i++ { - updateMemoryAttributes(&memParts.MemParts[i].Attribs) - if dedupeMemoryPart(dedupedParts, &memParts.MemParts[i]) == false { - generateSPD(&memParts.MemParts[i], SPDId, SPDDir) - SPDId++ - dedupedParts = append(dedupedParts, &memParts.MemParts[i]) - } - } - - if err := writeSPDManifest(&memParts, SPDDir); err != nil { - log.Fatal(err) - } -} -- cgit v1.2.3