~ $ git@github.com:oxidecomputer/helios.git
~ $ cd helios
helios $ gmake setup
[...snip...]
Setup complete! ./helios-build is now available.
helios $ ./helios-build build-illumos -dq
helios $ ./helios-build image -d -B -F optever=0.37.386 -F stress -F compliance -o /path/to/os-image
[...snip...]
Jul 04 00:22:25.000 INFO image complete! materials are in "/path/to/os-image"
~ $ git@github.com:oxidecomputer/dmar-report.git
~ $ cd dmar-report
dmar-report $ cargo build --release
~ $ mkdir tools
~ $ cp /path/to/helios/projects/amd-host-image-builder/target/debug/amd-host-image-builder tools/
~ $ cp /path/to/helios/projects/bootserver/target/release/bootserver tools/
~ $ cp /path/to/dmar-report/dmar-runner.py tools/
~ $ cp /path/to/dmar-report/target/release/dmar-report tools/
~ $ ls tools
amd-host-image-builder bootserver dmar-report dmar-runner.py
Can start with the (non-MBIST) image config in helios.
$ cp /path/to/helios/amd/turin-cosmo-a.efs.json5 turin-cosmo-a-mbist.efs.json5
Make sure BdatSupport and MemMbistDataEyeSilentExecutionDdr are Enabled. MemMbistDdrMode should be left Disabled. Otherwise, edit other tokens (e.g., MemMbistPatternLengthDdr, MemMbistAggressorsDdr) as desired.
$ grep -e Mbist -e Bdat turin-cosmo-a-mbist.efs.json5
MemMbistAggressorStaticLaneControl: false
MemMbistTgtStaticLaneControl: false
MemMbistAggressorsChannelDdrMode: "All"
MemMbistPatternLengthDdr: 6
MemMbistWorseCasGranularity: 0
MemMbistReadDataEyeVoltageStep: 1
MemMbistPerBitSlaveDieReportDdr: "Auto"
MemMbistAggressorStaticLaneVal: 0
MemMbistTgtStaticLaneVal: 0
MemMbistDataEyeType: "1D Timing"
MemMbistAggressorStaticLaneSelEcc: 0
MemMbistReadDataEyeTimingStep: 1
MemMbistPatternSelectDdr: "Both"
MemMbistDdrMode: "Disabled"
MemMbistDataEyeSilentExecutionDdr: "Enabled"
BdatSupport: "Enabled"
BdatPrintData: "Disabled"
MemMbistDataEyeExecutionRepeatCount: 1
MemMbistTestModeDdr: "Both"
MemMbistTgtStaticLaneSelEcc: 0
MemMbistHaltOnError: 1
MemMbistAggressorsDdr: "Enabled"
MemMbistWriteDataEyeVoltageStep: 1
MemMbistWriteDataEyeTimingStep: 1
MemMbistAggressorStaticLaneSelLo: 0
MemMbistTgtStaticLaneSelLo: 0
MemMbistTgtStaticLaneSelHi: 0
MemMbistAggressorStaticLaneSelHi: 0
$ IMAGE_DIR=/path/to/os-image
$ FW_PATH=/path/to/helios/projects/amd-firmware/BRH/1.0.0.5
$ /path/to/tools/dmar-runner.py -e $INVENTRON_NAME --fw-path $FW_PATH $IMAGE_DIR turin-cosmo-a-mbist.efs.json5 $HUMILITY_TARGET | tee run.log
DRAM Margining ( mb-3-sp )
Preparing target for testing...
Creating boot image...
Writing image to target...
humility: attached to 1fc9:0143:ANZ1BONHCHTRC via CMSIS-DAP
humility: erased 11.62MB in 46 seconds
humility: hashed 32.00MB, wrote 11.62MB in 8 minutes
Starting testing...
MBIST DataEye Test
AGESA complete
Booted to x86 (1:02:39.082458 elapsed)
Waiting for phase 2 request...
boot server starting on link e1000g0...
received hello! src e8:ea:6a:09:7f:64 dst ff:ff:ff:ff:ff:ff len 53
msg = "Hello! I'd like to buy a ramdisk please."
opened image "/staff/luqman/bringup/dram-margining/cosmo-mbist/zfs.img": image (data size 1048576000, image size 1048576000, target size 4294967296, hash 68daef27b18d0289946e239dc57775bc54e37b01a7f3ce01049da35081ddff7d, dataset rpool/ROOT/ramdisk)
progress: sent up to offset 911866880 (86%)
received finished! src e8:ea:6a:09:7f:64 dst 34:17:eb:d4:92:a6 len 46
finished copying!
Waiting for BRM13250005 to boot...
Begin DRAM Margining results collection...
DRAM Margining Test Results: BRM13250005-1986-12-28T-00-00-44.tar
(The -e flag may be omitted if $INVENTRON_NAME == $HUMILITY_TARGET)
The results will be in the outputted tarball:
$ tar xvf BRM13250005-1986-12-28T-00-00-44.tar
x BRM13250005, 0 bytes, 0 tape blocks
x BRM13250005/system_info.json, 310 bytes, 1 tape blocks
x BRM13250005/BDAT.bin, 2097152 bytes, 4096 tape blocks
x BRM13250005/SPD, 0 bytes, 0 tape blocks
x BRM13250005/SPD/chan_0_dimm_0.bin, 1024 bytes, 2 tape blocks
x BRM13250005/SPD/chan_0_dimm_0.json, 2977 bytes, 6 tape blocks
x BRM13250005/SPD/chan_1_dimm_0.bin, 1024 bytes, 2 tape blocks
x BRM13250005/SPD/chan_1_dimm_0.json, 2977 bytes, 6 tape blocks
x BRM13250005/SPD/chan_2_dimm_0.bin, 1024 bytes, 2 tape blocks
x BRM13250005/SPD/chan_2_dimm_0.json, 2977 bytes, 6 tape blocks
x BRM13250005/SPD/chan_3_dimm_0.bin, 1024 bytes, 2 tape blocks
x BRM13250005/SPD/chan_3_dimm_0.json, 2977 bytes, 6 tape blocks
x BRM13250005/SPD/chan_4_dimm_0.bin, 1024 bytes, 2 tape blocks
x BRM13250005/SPD/chan_4_dimm_0.json, 2977 bytes, 6 tape blocks
x BRM13250005/SPD/chan_5_dimm_0.bin, 1024 bytes, 2 tape blocks
x BRM13250005/SPD/chan_5_dimm_0.json, 2977 bytes, 6 tape blocks
x BRM13250005/SPD/chan_6_dimm_0.bin, 1024 bytes, 2 tape blocks
x BRM13250005/SPD/chan_6_dimm_0.json, 2995 bytes, 6 tape blocks
x BRM13250005/SPD/chan_7_dimm_0.bin, 1024 bytes, 2 tape blocks
x BRM13250005/SPD/chan_7_dimm_0.json, 2995 bytes, 6 tape blocks
x BRM13250005/SPD/chan_8_dimm_0.bin, 1024 bytes, 2 tape blocks
x BRM13250005/SPD/chan_8_dimm_0.json, 2995 bytes, 6 tape blocks
x BRM13250005/SPD/chan_9_dimm_0.bin, 1024 bytes, 2 tape blocks
x BRM13250005/SPD/chan_9_dimm_0.json, 2995 bytes, 6 tape blocks
x BRM13250005/SPD/chan_10_dimm_0.bin, 1024 bytes, 2 tape blocks
x BRM13250005/SPD/chan_10_dimm_0.json, 2995 bytes, 6 tape blocks
x BRM13250005/SPD/chan_11_dimm_0.bin, 1024 bytes, 2 tape blocks
x BRM13250005/SPD/chan_11_dimm_0.json, 2995 bytes, 6 tape blocks
x BRM13250005/dimms.json, 2259 bytes, 5 tape blocks
x BRM13250005/margins.json, 147171 bytes, 288 tape blocks
x BRM13250005/raw.json, 626644 bytes, 1224 tape blocks
x BRM13250005/mc_decode_snapshot.json, 44666 bytes, 88 tape blocks
This will give you the data eye width and height in UI and Volts, respectively:
$ jq <margins.json -r '["Channel", "DIMM", "Rank", "SubChannel", "Lane", "Read Width (UI)", "Read Height (V)", "Write Width (UI)", "Write Height (V)"], (.[] | .chan as $chan | .dimms | to_entries[] | (.key|tonumber) as $dimm | .value.ranks | to_entries[] | (.key|tonumber) as $rank | .value.sub_chans | to_entries[] | .key as $subchan | .value.data_eyes | to_entries[] | .key as $lane | .value | [$chan, $dimm, $rank, $subchan, $lane, .read[0], .read[1], .write[0], .write[1]]) | @csv'
"Channel","DIMM","Rank","SubChannel","Lane","Read Width (UI)","Read Height (V)","Write Width (UI)","Write Height (V)"
0,0,0,0,0,0.59375,0.09379700000000002,0.734375,0.21999999999999986
0,0,0,0,1,0.5625,0.09588699999999994,0.609375,0.22550000000000003
0,0,0,0,2,0.578125,0.10630399999999995,0.609375,0.2254999999999998
0,0,0,0,3,0.5625,0.10005600000000003,0.734375,0.21999999999999997
0,0,0,0,4,0.5625,0.10422500000000012,0.71875,0.21450000000000002
0,0,0,0,5,0.53125,0.10214600000000007,0.65625,0.19799999999999995
0,0,0,0,6,0.515625,0.11048400000000014,0.6875,0.19250000000000012
0,0,0,0,7,0.515625,0.1021350000000002,0.640625,0.1924999999999999
0,0,0,0,8,0.53125,0.08962799999999993,0.609375,0.1924999999999999
0,0,0,0,9,0.515625,0.10214600000000007,0.578125,0.21450000000000002
0,0,0,0,10,0.5625,0.10213499999999986,0.59375,0.21999999999999997
0,0,0,0,11,0.546875,0.07921099999999992,0.609375,0.2034999999999999
[...snip...]
This will give you the raw values usually seen in the ABL console output:
$ jq <raw.json -r '["Channel", "DIMM", "Rank", "SubChannel", "Lane", "Rd DqDelay (Left)", "Rd DqDelay (Right)", "Wr DqDelay (Left)", "Wr DqDelay (Right)", "Rd Vref (-)", "Rd Vref (+)", "Wr Vref (-)", "Wr Vref (+)"],(.[] | .chan as $chan | .dimms[] | .dimm as $dimm | .ranks[] | .rank as $rank | .sub_chans[] | .sub_chan as $subchan | .margins | to_entries[] | .key as $lane | .value | [$chan, $dimm, $rank, $subchan, $lane, .rd_dq_delay[0], .rd_dq_delay[1], .wr_dq_delay[0], .wr_dq_delay[1], .rd_vref[0], .rd_vref[1], .wr_vref[0], .wr_vref[1]]) | @csv'
"Channel","DIMM","Rank","SubChannel","Lane","Rd DqDelay (Left)","Rd DqDelay (Right)","Wr DqDelay (Left)","Wr DqDelay (Right)","Rd Vref (-)","Rd Vref (+)","Wr Vref (-)","Wr Vref (+)"
0,0,0,0,0,14,24,22,25,17,13,19,19
0,0,0,0,1,14,22,21,18,18,13,18,21
0,0,0,0,2,14,23,20,19,23,13,19,20
0,0,0,0,3,14,22,22,25,20,13,21,17
0,0,0,0,4,17,19,23,23,22,13,18,19
0,0,0,0,5,17,17,21,21,21,13,17,17
0,0,0,0,6,17,16,21,23,25,13,15,18
0,0,0,0,7,17,16,21,20,21,13,16,17
0,0,0,0,8,15,19,20,19,15,13,16,17
0,0,0,0,9,15,18,18,19,21,13,18,19
0,0,0,0,10,15,21,19,19,21,13,18,20
0,0,0,0,11,15,20,20,19,10,13,16,19
[...snip...]