1 // 2 // Copyright (c) 2010-2023 Antmicro 3 // 4 // This file is licensed under the MIT License. 5 // Full license text is available in 'licenses/MIT.txt'. 6 // 7 using System.Collections.Generic; 8 using Antmicro.Renode.Exceptions; 9 using Antmicro.Renode.Peripherals.Memory; 10 using Antmicro.Renode.Utilities; 11 12 namespace Antmicro.Renode.Peripherals.SPI 13 { 14 public class Cypress_S25H : GenericSpiFlash 15 { Cypress_S25H(MappedMemory underlyingMemory, S25HxFamily memoryFamily = S25HxFamily.HS_T)16 public Cypress_S25H(MappedMemory underlyingMemory, S25HxFamily memoryFamily = S25HxFamily.HS_T) 17 : base(underlyingMemory, manufacturerId: ManufacturerId, memoryType: (byte)memoryFamily, 18 writeStatusCanSetWriteEnable: true, extendedDeviceId: ExtendedDeviceID, 19 remainingIdBytes: RemainingIDBytes, deviceConfiguration: DeviceConfiguration, 20 sectorSizeKB: SectorSizeKB) 21 { 22 if(underlyingMemory.Size < 32.MB() || underlyingMemory.Size > 128.MB()) 23 { 24 throw new ConstructionException("Size of the underlying memory must be in range 32MB - 128MB"); 25 } 26 } 27 GetCapacityCode()28 protected override byte GetCapacityCode() 29 { 30 // S25Hx family of flash chips ignore assumption that 64 MB and larger memories 31 // has capacity codes starting from 0x20, leaving a gap from 0x1A to 0x1F. 32 return (byte)BitHelper.GetMostSignificantSetBitIndex((ulong)this.UnderlyingMemory.Size); 33 } 34 GetSFDPSignature()35 protected override byte[] GetSFDPSignature() 36 { 37 byte[] patchedSFDPSignature = DefaultSFDPSignature; 38 byte capacity = GetCapacityCode(); 39 40 // Some values in parameters differ between flash size variants. 41 // Outer dictionary uses capacity code as a key to select offset-value 42 // pairs applied to default SFDP signature. 43 44 // Patched DWORDs: 45 // - Basic Flash Parameter DWORD-2 (0x107), DWORD-11 (0x12B) 46 // - Sector Map Parameter DWORD-10 Config-0 Region-2 (0x1EF) 47 // - Sector Map Parameter DWORD-12 Config-3 Region-0 (0x1F7) 48 // - Sector Map Parameter DWORD-18 Config-1 Region-2 (0x20F) 49 // - Sector Map Parameter DWORD-22 Config-4 Region-0 (0x21F) 50 var patchtable = new Dictionary<byte, Dictionary<ulong, byte>>() { 51 {0x19, new Dictionary<ulong, byte>() { 52 {0x107, 0x0F}, 53 {0x12B, 0xE1}, 54 {0x1EF, 0x01}, 55 {0x1F7, 0x01}, 56 {0x20F, 0x01}, 57 {0x21F, 0x01} 58 }}, 59 {0x1a, new Dictionary<ulong, byte>() { 60 {0x107, 0x1F}, 61 {0x12B, 0xE3}, 62 {0x1EF, 0x03}, 63 {0x1F7, 0x03}, 64 {0x20F, 0x03}, 65 {0x21F, 0x03} 66 }}, 67 {0x1b, new Dictionary<ulong, byte>() { 68 {0x107, 0x3F}, 69 {0x12B, 0xE6}, 70 {0x1EF, 0x07}, 71 {0x1F7, 0x07}, 72 {0x20F, 0x07}, 73 {0x21F, 0x07} 74 }} 75 }; 76 77 foreach(var patch in patchtable[capacity]) 78 { 79 patchedSFDPSignature[patch.Key] = patch.Value; 80 } 81 82 return patchedSFDPSignature; 83 } 84 GetDummyBytes(Commands command)85 protected override int GetDummyBytes(Commands command) 86 { 87 switch(command) 88 { 89 case Commands.ReadSerialFlashDiscoveryParameter: 90 return 1; 91 default: 92 return base.GetDummyBytes(command); 93 } 94 } 95 96 private const byte ManufacturerId = 0x34; 97 private const byte MemoryType = 0x2B; // HS-T: 0x2B, HL-T: 0x2A 98 private const byte RemainingIDBytes = 0x0F; 99 private const byte ExtendedDeviceID = 0x03; 100 private const byte DeviceConfiguration = 0x90; 101 private const int SectorSizeKB = 256; 102 103 private readonly byte[] DefaultSFDPSignature = new byte[] 104 { 105 // SFDP Rev D header table 106 0x53, 0x46, 0x44, 0x50, 0x08, 0x01, 0x03, 0xff, 0x00, 0x00, 107 0x01, 0x14, 0x00, 0x01, 0x00, 0xff, 0x84, 0x00, 0x01, 0x02, 108 0x50, 0x01, 0x00, 0xff, 0x81, 0x00, 0x01, 0x16, 0xc8, 0x01, 109 0x00, 0xff, 0x84, 0x00, 0x01, 0x1c, 0x58, 0x01, 0x00, 0xff, 110 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 111 // Values below are not consistent with the spec 112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 114 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 117 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 118 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 120 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 122 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 123 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 125 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 126 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 127 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 128 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 130 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 131 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 132 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 133 // SFDP Rev D parameter table 134 0xe7, 0x20, 0xfa, 0xff, 0xff, 0xff, 0xff, 0x1F, 0x48, 0xeb, //0x107: 0x0f/1f/3f 135 0x08, 0x6b, 0x00, 0xff, 0x88, 0xbb, 0xfe, 0xff, 0xff, 0xff, 136 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x48, 0xeb, 0x0c, 0x20, 137 0x00, 0xff, 0x00, 0xff, 0x12, 0xd8, 0x23, 0xfa, 0xff, 0x8b, 138 0x82, 0xe7, 0xff, 0xE3, 0xec, 0x23, 0x19, 0x49, 0x8a, 0x85, //0x12B: 0xe1/e3/e6 139 0x7a, 0x75, 0xf7, 0x66, 0x80, 0x5c, 0x8c, 0xd6, 0xdd, 0xff, 140 0xf9, 0x38, 0xf8, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 141 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0xf5, 0xff, 0xff, 142 0x7b, 0x92, 0x0f, 0xfe, 0x21, 0xff, 0xff, 0xdc, 0x00, 0x00, 143 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xc3, 0xeb, 144 0xc8, 0xff, 0xe3, 0xeb, 0x00, 0x65, 0x00, 0x90, 0x06, 0x05, 145 0x00, 0xa1, 0x00, 0x65, 0x00, 0x96, 0x00, 0x65, 0x00, 0x65, 146 0x71, 0x65, 0x03, 0xd0, 0x71, 0x65, 0x03, 0xd0, 0x00, 0x00, 147 0x00, 0x00, 0xb0, 0x2e, 0x00, 0x00, 0x88, 0xa4, 0x89, 0xaa, 148 0x71, 0x65, 0x03, 0x96, 0x71, 0x65, 0x03, 0x96, 0x00, 0x00, 149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x65, 153 0x05, 0xd5, 0x71, 0x65, 0x05, 0xd5, 0x00, 0x00, 0xa0, 0x15, 154 // SFDP rev D sector map parameter table 155 0xFC, 0x65, 0xFF, 0x08, 0x04, 0x00, 0x80, 0x00, 0xFC, 0x65, 156 0xFF, 0x40, 0x02, 0x00, 0x80, 0x00, 0xFD, 0x65, 0xFF, 0x04, 157 0x02, 0x00, 0x80, 0x00, 0xFE, 0x00, 0x02, 0xFF, 0xF1, 0xFF, 158 0x01, 0x00, 0xF8, 0xFF, 0x01, 0x00, 0xF8, 0xFF, 0xFB, 0x03, //0x1EF: 0x01/03/07 159 0xFE, 0x01, 0x02, 0xFF, 0xF8, 0xFF, 0xFB, 0x03, 0xF8, 0xFF, //0x1F7: 0x01/03/07 160 0x01, 0x00, 0xF1, 0xFF, 0x01, 0x00, 0xFE, 0x02, 0x04, 0xFF, 161 0xF1, 0xFF, 0x00, 0x00, 0xF8, 0xFF, 0x02, 0x00, 0xF8, 0xFF, 162 0xF7, 0x03, 0xF8, 0xFF, 0x02, 0x00, 0xF1, 0xFF, 0x00, 0x00, //0x20F: 0x01/03/07 163 0xFF, 0x04, 0x00, 0xFF, 0xF8, 0xFF, 0xFF, 0x03 //0x21F: 0x01/03/07 164 }; 165 166 public enum S25HxFamily : byte 167 { 168 HL_T = 0x2A, 169 HS_T = 0x2B 170 } 171 } 172 } 173