github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/pkg/flash/sfdp/sfdp_test.go (about)

     1  // Copyright 2021 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package sfdp
     6  
     7  import (
     8  	"bytes"
     9  	"errors"
    10  	"io"
    11  	"testing"
    12  
    13  	"github.com/mvdan/u-root-coreutils/pkg/flash/spimock"
    14  )
    15  
    16  // fakeSFDPPrettyPrint corresponds to the pretty print of spimock.FakeSFDP.
    17  var fakeSFDPPrettyPrint = `BlockSectorEraseSize           0x1
    18  WriteGranularity               0x1
    19  WriteEnableInstructionRequired 0x0
    20  WriteEnableOpcodeSelect        0x0
    21  4KBEraseOpcode                 0x20
    22  112FastRead                    0x1
    23  AddressBytesNumberUsed         0x1
    24  DoubleTransferRateClocking     0x0
    25  122FastReadSupported           0x1
    26  144FastReadSupported           0x1
    27  114FastReadSupported           0x1
    28  FlashMemoryDensity             0x1fffffff
    29  144FastReadNumberOfWaitStates  0x4
    30  144FastReadNumberOfModeBits    0x2
    31  144FastReadOpcode              0xeb
    32  114FastReadNumberOfWaitStates  0x8
    33  114FastReadNumberOfModeBits    0x0
    34  114FastReadOpcode              0x6b
    35  112FastReadNumberOfWaitStates  0x8
    36  112FastReadNumberOfModeBits    0x0
    37  112FastReadOpcode              0x3b
    38  122FastReadNumberOfWaitStates  0x4
    39  122FastReadNumberOfModeBits    0x0
    40  122FastReadOpcode              0xbb
    41  222FastReadSupported           0x0
    42  444FastReadSupported           0x1
    43  `
    44  
    45  // errorLookupParams contains Params which will return an error when read.
    46  var errorLookupParams = []ParamLookupEntry{
    47  	{"ExistingParam", Param{0, 0, 0x00, 0x20}},
    48  	{"NonExistingTable", Param{0x999, 0, 0x00, 0x20}},
    49  	{"NonExistingDword", Param{0, 0x999, 0x00, 0x20}},
    50  }
    51  
    52  // errorPrettyPrint corresponds to the pretty print of spimock.FakeSFDP for the
    53  // Params in errorLookupParams.
    54  var errorPrettyPrint = `ExistingParam    0xfff320e5
    55  NonExistingTable Error: could not find table 0x999
    56  NonExistingDword Error: could not find dword 0x999 in table 0x0
    57  `
    58  
    59  // TestPrettyPrint prints the SFDP to a beatiful string.
    60  func TestPrettyPrint(t *testing.T) {
    61  	for _, tt := range []struct {
    62  		name        string
    63  		fakeSFDP    []byte
    64  		paramLookup []ParamLookupEntry
    65  		prettyPrint string
    66  	}{
    67  		{
    68  			name:        "MX66L51235F",
    69  			fakeSFDP:    spimock.FakeSFDP,
    70  			paramLookup: BasicTableLookup,
    71  			prettyPrint: fakeSFDPPrettyPrint,
    72  		},
    73  		{
    74  			name:        "error prints",
    75  			fakeSFDP:    spimock.FakeSFDP,
    76  			paramLookup: errorLookupParams,
    77  			prettyPrint: errorPrettyPrint,
    78  		},
    79  	} {
    80  		t.Run(tt.name, func(t *testing.T) {
    81  			r := bytes.NewReader(tt.fakeSFDP)
    82  			sfdp, err := Read(r)
    83  			if err != nil {
    84  				t.Fatal(err)
    85  			}
    86  
    87  			w := &bytes.Buffer{}
    88  			if err := sfdp.PrettyPrint(w, tt.paramLookup); err != nil {
    89  				t.Fatal(err)
    90  			}
    91  
    92  			if w.String() != tt.prettyPrint {
    93  				t.Errorf("sfdp.PrettyPrint() =\n%s\n;want\n%s", w.String(), tt.prettyPrint)
    94  			}
    95  		})
    96  	}
    97  }
    98  
    99  func TestRead(t *testing.T) {
   100  	for _, tt := range []struct {
   101  		name      string
   102  		fakeSFDP  []byte
   103  		wantError error
   104  	}{
   105  		{
   106  			name:     "successful",
   107  			fakeSFDP: spimock.FakeSFDP,
   108  		},
   109  		{
   110  			name:      "magic not found",
   111  			fakeSFDP:  spimock.FakeSFDP[4:],
   112  			wantError: &UnsupportedError{},
   113  		},
   114  		{
   115  			// Induce an EOF reader error with an empty buffer.
   116  			name:      "reader error",
   117  			fakeSFDP:  []byte{},
   118  			wantError: io.EOF,
   119  		},
   120  		{
   121  			// Induce a reader error on the tables with a truncated
   122  			// buffer.
   123  			name:      "reader table error",
   124  			fakeSFDP:  spimock.FakeSFDP[:0x30],
   125  			wantError: io.EOF,
   126  		},
   127  	} {
   128  		t.Run(tt.name, func(t *testing.T) {
   129  			r := bytes.NewReader(tt.fakeSFDP)
   130  			_, err := Read(r)
   131  			if !errors.Is(err, tt.wantError) {
   132  				t.Errorf("sfdp.Read() err = %v; want %v", err, tt.wantError)
   133  			}
   134  		})
   135  	}
   136  }
   137  
   138  // TestRead16BitId checks that the v1.5 16-bit table IDs are supported.
   139  func TestRead16BitId(t *testing.T) {
   140  	sfdpV1_5 := []byte{
   141  		// 0x00: Magic
   142  		0x53, 0x46, 0x44, 0x50,
   143  		// 0x04: Version v1.5
   144  		0x05, 0x01,
   145  		// 0x06: Number of headers, 0 means there's 1 header
   146  		0x00,
   147  		// 0x07: Unused
   148  		0x00,
   149  		// 0x08: Parameter header ID LSB
   150  		0xcd,
   151  		// 0x09: Version v1.0
   152  		0x00, 0x01,
   153  		// 0x0b: Number of DWORDS in the table
   154  		0x01,
   155  		// 0x0c: Pointer
   156  		0x10, 0x00, 0x00,
   157  		// 0x0f: ID MSB
   158  		0xab,
   159  		// 0x10: DWORD 0
   160  		0x78, 0x56, 0x34, 0x12,
   161  	}
   162  
   163  	r := bytes.NewReader(sfdpV1_5)
   164  	sfdp, err := Read(r)
   165  	if err != nil {
   166  		t.Fatal(err)
   167  	}
   168  
   169  	testParam := Param{
   170  		Table: 0xabcd,
   171  		Dword: 0,
   172  		Shift: 0,
   173  		Bits:  32,
   174  	}
   175  
   176  	val, err := sfdp.Param(testParam)
   177  	if err != nil {
   178  		t.Error(err)
   179  	}
   180  	var want int64 = 0x12345678
   181  	if val != want {
   182  		t.Errorf("sfdp.Param() = %#x; want %#x", val, want)
   183  	}
   184  }