1*0cbe4818SRobert Mustacchi#! /usr/bin/ksh 2*0cbe4818SRobert Mustacchi# 3*0cbe4818SRobert Mustacchi# This file and its contents are supplied under the terms of the 4*0cbe4818SRobert Mustacchi# Common Development and Distribution License ("CDDL"), version 1.0. 5*0cbe4818SRobert Mustacchi# You may only use this file in accordance with the terms of version 6*0cbe4818SRobert Mustacchi# 1.0 of the CDDL. 7*0cbe4818SRobert Mustacchi# 8*0cbe4818SRobert Mustacchi# A full copy of the text of the CDDL should have accompanied this 9*0cbe4818SRobert Mustacchi# source. A copy of the CDDL is also available via the Internet at 10*0cbe4818SRobert Mustacchi# http://www.illumos.org/license/CDDL. 11*0cbe4818SRobert Mustacchi# 12*0cbe4818SRobert Mustacchi 13*0cbe4818SRobert Mustacchi# 14*0cbe4818SRobert Mustacchi# Copyright 2025 Oxide Computer Company 15*0cbe4818SRobert Mustacchi# 16*0cbe4818SRobert Mustacchi 17*0cbe4818SRobert Mustacchi# 18*0cbe4818SRobert Mustacchi# Perform various I/O tests against our virtual devices. Several of the at24c 19*0cbe4818SRobert Mustacchi# devices have content pre-loaded into them with parts of Tolkienian rhymes. We 20*0cbe4818SRobert Mustacchi# can only perform SMBus operations against the at24c08 as the others require a 21*0cbe4818SRobert Mustacchi# two byte I/O pattern. 22*0cbe4818SRobert Mustacchi# 23*0cbe4818SRobert Mustacchi 24*0cbe4818SRobert Mustacchi. $(dirname $0)/common.ksh 25*0cbe4818SRobert Mustacchi 26*0cbe4818SRobert Mustacchi# 27*0cbe4818SRobert Mustacchi# Variable where the results of performing I/O will be sent. 28*0cbe4818SRobert Mustacchi# 29*0cbe4818SRobert Mustacchiio_data= 30*0cbe4818SRobert Mustacchiio_eedev= 31*0cbe4818SRobert Mustacchiio_dd= 32*0cbe4818SRobert Mustacchi 33*0cbe4818SRobert Mustacchifunction i2c_at24c_to_eedev 34*0cbe4818SRobert Mustacchi{ 35*0cbe4818SRobert Mustacchi typeset path="$1" 36*0cbe4818SRobert Mustacchi typeset drv="$2" 37*0cbe4818SRobert Mustacchi typeset part= 38*0cbe4818SRobert Mustacchi 39*0cbe4818SRobert Mustacchi part=$(i2cadm device list -Hpo instance $path | sed "s/$drv/$drv\//") 40*0cbe4818SRobert Mustacchi [[ -z "$part" ]] && fatal "failed to translate $path" 41*0cbe4818SRobert Mustacchi io_eedev="/dev/eeprom/$part/eeprom" 42*0cbe4818SRobert Mustacchi} 43*0cbe4818SRobert Mustacchi 44*0cbe4818SRobert Mustacchifunction do_io 45*0cbe4818SRobert Mustacchi{ 46*0cbe4818SRobert Mustacchi io_data=$($I2CADM io -o /dev/stdout $@) 47*0cbe4818SRobert Mustacchi if (( $? != 0 )); then 48*0cbe4818SRobert Mustacchi fatal "failed to perform I/O $@" 49*0cbe4818SRobert Mustacchi fi 50*0cbe4818SRobert Mustacchi} 51*0cbe4818SRobert Mustacchi 52*0cbe4818SRobert Mustacchifunction check_io 53*0cbe4818SRobert Mustacchi{ 54*0cbe4818SRobert Mustacchi typeset desc="$1" 55*0cbe4818SRobert Mustacchi typeset targ="$2" 56*0cbe4818SRobert Mustacchi shift 57*0cbe4818SRobert Mustacchi shift 58*0cbe4818SRobert Mustacchi 59*0cbe4818SRobert Mustacchi do_io $@ 60*0cbe4818SRobert Mustacchi if [[ "$targ" != "$io_data" ]]; then 61*0cbe4818SRobert Mustacchi warn "$desc: I/O mismatch: found [$io_data], expected [$targ]" 62*0cbe4818SRobert Mustacchi else 63*0cbe4818SRobert Mustacchi printf "TEST PASSED: %s\n" "$desc" 64*0cbe4818SRobert Mustacchi fi 65*0cbe4818SRobert Mustacchi} 66*0cbe4818SRobert Mustacchi 67*0cbe4818SRobert Mustacchifunction get_dd 68*0cbe4818SRobert Mustacchi{ 69*0cbe4818SRobert Mustacchi typeset off="$1" 70*0cbe4818SRobert Mustacchi typeset len="$2" 71*0cbe4818SRobert Mustacchi 72*0cbe4818SRobert Mustacchi [[ -z "$io_eedev" ]] && fatal "missing required eedev path" 73*0cbe4818SRobert Mustacchi 74*0cbe4818SRobert Mustacchi io_dd=$(dd iseek=$off bs=1 count="$len" if=$io_eedev of=/dev/stdout \ 75*0cbe4818SRobert Mustacchi status=none) 76*0cbe4818SRobert Mustacchi if (( $? != 0 )); then 77*0cbe4818SRobert Mustacchi fatal "failed to dd on $io_eedev" 78*0cbe4818SRobert Mustacchi fi 79*0cbe4818SRobert Mustacchi} 80*0cbe4818SRobert Mustacchi 81*0cbe4818SRobert Mustacchifunction compare_io_dd 82*0cbe4818SRobert Mustacchi{ 83*0cbe4818SRobert Mustacchi typeset desc="$1" 84*0cbe4818SRobert Mustacchi 85*0cbe4818SRobert Mustacchi if [[ "$io_dd" != "$io_data" ]]; then 86*0cbe4818SRobert Mustacchi warn "$desc: dd and i2c disagree, found $io_dd (dd) and " \ 87*0cbe4818SRobert Mustacchi "$io_data (i2c)" 88*0cbe4818SRobert Mustacchi else 89*0cbe4818SRobert Mustacchi printf "TEST PASSED: %s\n" "$desc" 90*0cbe4818SRobert Mustacchi fi 91*0cbe4818SRobert Mustacchi} 92*0cbe4818SRobert Mustacchi 93*0cbe4818SRobert Mustacchifunction write_io 94*0cbe4818SRobert Mustacchi{ 95*0cbe4818SRobert Mustacchi typeset desc="$1" 96*0cbe4818SRobert Mustacchi typeset targ="$2" 97*0cbe4818SRobert Mustacchi typeset len="$3" 98*0cbe4818SRobert Mustacchi typeset off="$4" 99*0cbe4818SRobert Mustacchi typeset dev="$5" 100*0cbe4818SRobert Mustacchi shift 101*0cbe4818SRobert Mustacchi shift 102*0cbe4818SRobert Mustacchi shift 103*0cbe4818SRobert Mustacchi shift 104*0cbe4818SRobert Mustacchi shift 105*0cbe4818SRobert Mustacchi 106*0cbe4818SRobert Mustacchi # 107*0cbe4818SRobert Mustacchi # Bump len by one to write the offset 108*0cbe4818SRobert Mustacchi # 109*0cbe4818SRobert Mustacchi if ! $I2CADM io -d "$dev" $@; then 110*0cbe4818SRobert Mustacchi fatal "failed to perform I/O $@" 111*0cbe4818SRobert Mustacchi fi 112*0cbe4818SRobert Mustacchi 113*0cbe4818SRobert Mustacchi check_io "$desc" "$targ" -d $dev -w 1 -r $len $off 114*0cbe4818SRobert Mustacchi} 115*0cbe4818SRobert Mustacchi 116*0cbe4818SRobert Mustacchi# 117*0cbe4818SRobert Mustacchi# First Verify that basic I/O makes sense. 118*0cbe4818SRobert Mustacchi# 119*0cbe4818SRobert Mustacchicheck_io "Three Rings i2c" "Three rings" -d i2csim0/0/0x20 -r 11 -w 1 0x00 120*0cbe4818SRobert Mustacchicheck_io "Three Rings offset i2c" "rings" -d i2csim0/0/0x20 -r 5 -w 1 0x06 121*0cbe4818SRobert Mustacchicheck_io "Three Rings recv-u8 (1)" " " -d i2csim0/0/0x20 -m recv-u8 122*0cbe4818SRobert Mustacchicheck_io "Three Rings recv-u8 (2)" "f" -d i2csim0/0/0x20 -m recv-u8 123*0cbe4818SRobert Mustacchicheck_io "Three Rings read-u8 (1)" "E" -d i2csim0/0/0x20 -m read-u8 -c 0x10 124*0cbe4818SRobert Mustacchicheck_io "Three Rings read-u8 (2)" "-" -d i2csim0/0/0x20 -m read-u8 -c 0x15 125*0cbe4818SRobert Mustacchicheck_io "Three Rings read-u16" "El" -d i2csim0/0/0x20 -m read-u16 -c 0x10 126*0cbe4818SRobert Mustacchicheck_io "Three Rings read-u32" "king" -d i2csim0/0/0x20 -m read-u32 -c 0x16 127*0cbe4818SRobert Mustacchicheck_io "Three Rings read-u64" "the sky," -d i2csim0/0/0x20 -m read-u64 -c 0x23 128*0cbe4818SRobert Mustacchicheck_io "Three Rings read-block-i2c" "Elven-kings, und" -d i2csim0/0/0x20 \ 129*0cbe4818SRobert Mustacchi -m read-block-i2c -c 0x10 -r 0x10 130*0cbe4818SRobert Mustacchicheck_io "Three Rings i2c (all)" "Three rings for Elven-kings, under the sky," \ 131*0cbe4818SRobert Mustacchi -d i2csim0/0/0x20 -r 0x2b -w 1 0x00 132*0cbe4818SRobert Mustacchicheck_io "Three Rings block (all)" "Three rings for Elven-kings, under the sky," \ 133*0cbe4818SRobert Mustacchi -d i2csim0/0/0x20 -m read-block-i2c -c 0x00 -r 0x2b 134*0cbe4818SRobert Mustacchi 135*0cbe4818SRobert Mustacchi# 136*0cbe4818SRobert Mustacchi# Next, we want to verify that using /dev/eeprom and the io mechanism is 137*0cbe4818SRobert Mustacchi# similar. First we'll verify reads across all the different segments of the 138*0cbe4818SRobert Mustacchi# at24c08. 139*0cbe4818SRobert Mustacchi# 140*0cbe4818SRobert Mustacchii2c_at24c_to_eedev i2csim0/0/0x20 at24c 141*0cbe4818SRobert Mustacchiget_dd 0 43 142*0cbe4818SRobert Mustacchicompare_io_dd "at24cs08 block 0 comparison" 143*0cbe4818SRobert Mustacchi 144*0cbe4818SRobert Mustacchicheck_io "Seven i2c (all)" "Seven for the Dwarf-lords in their halls of stone," \ 145*0cbe4818SRobert Mustacchi -d i2csim0/0 -a 0x21 -r 0x32 -w 1 0x00 146*0cbe4818SRobert Mustacchiget_dd 256 50 147*0cbe4818SRobert Mustacchicompare_io_dd "at24cs08 block 1 comparison" 148*0cbe4818SRobert Mustacchi 149*0cbe4818SRobert Mustacchicheck_io "Nine i2c (all)" "Nine for Moral Men, doomed to die," \ 150*0cbe4818SRobert Mustacchi -d i2csim0/0 -a 0x22 -r 0x22 -w 1 0x00 151*0cbe4818SRobert Mustacchiget_dd 512 34 152*0cbe4818SRobert Mustacchicompare_io_dd "at24cs08 block 2 comparison" 153*0cbe4818SRobert Mustacchi 154*0cbe4818SRobert Mustacchicheck_io "One i2c (all)" "One for the dark Lord on his dark throne" \ 155*0cbe4818SRobert Mustacchi -d i2csim0/0 -a 0x23 -r 0x28 -w 1 0x00 156*0cbe4818SRobert Mustacchiget_dd 768 40 157*0cbe4818SRobert Mustacchicompare_io_dd "at24cs08 block 3 comparison" 158*0cbe4818SRobert Mustacchi 159*0cbe4818SRobert Mustacchi# 160*0cbe4818SRobert Mustacchi# Now it's time to do our write testing. One caveat with the at24c08 is that 161*0cbe4818SRobert Mustacchi# writes that are larger than a 16-byte segment will wrap and start over at the 162*0cbe4818SRobert Mustacchi# beginning. This means that we'll need to be a bit more mindful of our offsets. 163*0cbe4818SRobert Mustacchi# We start an offset of 128 (0x80) to avoid our existing data. 164*0cbe4818SRobert Mustacchi# 165*0cbe4818SRobert Mustacchiwrite_io "i2c write" "All that is gold" 16 0x80 i2csim0/0/0x20 -w 17 0x80 0x41 \ 166*0cbe4818SRobert Mustacchi 0x6c 0x6c 0x20 0x74 0x68 0x61 0x74 0x20 0x69 0x73 0x20 0x67 0x6f 0x6c 0x64 167*0cbe4818SRobert Mustacchiget_dd 128 16 168*0cbe4818SRobert Mustacchicompare_io_dd "All that is gold i2c write" 169*0cbe4818SRobert Mustacchiwrite_io "write-u8" " " 1 0x90 i2csim0/0/0x20 -m write-u8 -c 0x90 0x20 170*0cbe4818SRobert Mustacchiwrite_io "write-u16" "do" 2 0x91 i2csim0/0/0x20 -m write-u16 -c 0x91 0x6f64 171*0cbe4818SRobert Mustacchiwrite_io "write-u8" "e" 1 0x93 i2csim0/0/0x20 -m write-u8 -c 0x93 0x65 172*0cbe4818SRobert Mustacchiwrite_io "write-u32" "s no" 4 0x94 i2csim0/0/0x20 -m write-u32 -c 0x94 \ 173*0cbe4818SRobert Mustacchi 0x6f6e2073 174*0cbe4818SRobert Mustacchiwrite_io "write-u64" "t glitte" 8 0x98 i2csim0/0/0x20 -m write-u64 -c 0x98 \ 175*0cbe4818SRobert Mustacchi 0x657474696c672074 176*0cbe4818SRobert Mustacchicheck_io "write stanza 2 (block)" " does not glitte" -d i2csim0/0/0x20 \ 177*0cbe4818SRobert Mustacchi -m read-block-i2c -c 0x90 -r 0x10 178*0cbe4818SRobert Mustacchiget_dd 144 16 179*0cbe4818SRobert Mustacchicompare_io_dd "does not glitter i2c write" 180*0cbe4818SRobert Mustacchi 181*0cbe4818SRobert Mustacchi# 182*0cbe4818SRobert Mustacchi# Do a 16 byte block write over the existing portion and show that it 183*0cbe4818SRobert Mustacchi# overwrites. Do this manually as the general I/O check logic is going to have 184*0cbe4818SRobert Mustacchi# trouble with this. This takes the string 'r, Not all those' and offsets it 4 185*0cbe4818SRobert Mustacchi# bytes. 186*0cbe4818SRobert Mustacchi# 187*0cbe4818SRobert Mustacchiif ! $I2CADM io -d i2csim0/0/0x20 -m write-block-i2c -c 0x94 -w 16 \ 188*0cbe4818SRobert Mustacchi 0x72 0x2c 0x20 0x4e 0x6f 0x74 0x20 0x61 0x6c 0x6c 0x20 0x74 0x68 0x6f 0x73 \ 189*0cbe4818SRobert Mustacchi 0x65; then 190*0cbe4818SRobert Mustacchi fatal "failed to perform i2c block write" 191*0cbe4818SRobert Mustacchifi 192*0cbe4818SRobert Mustacchicheck_io "write stanza 3 (block)" "hoser, Not all t" -d i2csim0/0/0x20 \ 193*0cbe4818SRobert Mustacchi -m read-block-i2c -c 0x90 -r 0x10 194*0cbe4818SRobert Mustacchiget_dd 144 16 195*0cbe4818SRobert Mustacchicompare_io_dd "i2c block overwrite" 196*0cbe4818SRobert Mustacchi 197*0cbe4818SRobert Mustacchiif (( i2c_exit == 0 )); then 198*0cbe4818SRobert Mustacchi printf "All tests passed successfully!\n" 199*0cbe4818SRobert Mustacchifi 200*0cbe4818SRobert Mustacchi 201*0cbe4818SRobert Mustacchiexit $i2c_exit 202