1 /* 2 * QEMU SiFive U OTP (One-Time Programmable) Memory interface 3 * 4 * Copyright (c) 2019 Bin Meng <bmeng.cn@gmail.com> 5 * 6 * Simple model of the OTP to emulate register reads made by the SDK BSP 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms and conditions of the GNU General Public License, 10 * version 2 or later, as published by the Free Software Foundation. 11 * 12 * This program is distributed in the hope it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15 * more details. 16 * 17 * You should have received a copy of the GNU General Public License along with 18 * this program. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #include "qemu/osdep.h" 22 #include "qapi/error.h" 23 #include "hw/qdev-properties.h" 24 #include "hw/qdev-properties-system.h" 25 #include "hw/sysbus.h" 26 #include "qemu/log.h" 27 #include "qemu/module.h" 28 #include "hw/misc/sifive_u_otp.h" 29 #include "sysemu/blockdev.h" 30 #include "sysemu/block-backend.h" 31 32 #define WRITTEN_BIT_ON 0x1 33 34 #define SET_FUSEARRAY_BIT(map, i, off, bit) \ 35 map[i] = bit ? (map[i] | bit << off) : (map[i] & ~(0x1 << off)) 36 37 #define GET_FUSEARRAY_BIT(map, i, off) \ 38 ((map[i] >> off) & 0x1) 39 40 static uint64_t sifive_u_otp_read(void *opaque, hwaddr addr, unsigned int size) 41 { 42 SiFiveUOTPState *s = opaque; 43 44 switch (addr) { 45 case SIFIVE_U_OTP_PA: 46 return s->pa; 47 case SIFIVE_U_OTP_PAIO: 48 return s->paio; 49 case SIFIVE_U_OTP_PAS: 50 return s->pas; 51 case SIFIVE_U_OTP_PCE: 52 return s->pce; 53 case SIFIVE_U_OTP_PCLK: 54 return s->pclk; 55 case SIFIVE_U_OTP_PDIN: 56 return s->pdin; 57 case SIFIVE_U_OTP_PDOUT: 58 if ((s->pce & SIFIVE_U_OTP_PCE_EN) && 59 (s->pdstb & SIFIVE_U_OTP_PDSTB_EN) && 60 (s->ptrim & SIFIVE_U_OTP_PTRIM_EN)) { 61 62 /* read from backend */ 63 if (s->blk) { 64 int32_t buf; 65 66 blk_pread(s->blk, s->pa * SIFIVE_U_OTP_FUSE_WORD, &buf, 67 SIFIVE_U_OTP_FUSE_WORD); 68 return buf; 69 } 70 71 return s->fuse[s->pa & SIFIVE_U_OTP_PA_MASK]; 72 } else { 73 return 0xff; 74 } 75 case SIFIVE_U_OTP_PDSTB: 76 return s->pdstb; 77 case SIFIVE_U_OTP_PPROG: 78 return s->pprog; 79 case SIFIVE_U_OTP_PTC: 80 return s->ptc; 81 case SIFIVE_U_OTP_PTM: 82 return s->ptm; 83 case SIFIVE_U_OTP_PTM_REP: 84 return s->ptm_rep; 85 case SIFIVE_U_OTP_PTR: 86 return s->ptr; 87 case SIFIVE_U_OTP_PTRIM: 88 return s->ptrim; 89 case SIFIVE_U_OTP_PWE: 90 return s->pwe; 91 } 92 93 qemu_log_mask(LOG_GUEST_ERROR, "%s: read: addr=0x%" HWADDR_PRIx "\n", 94 __func__, addr); 95 return 0; 96 } 97 98 static void sifive_u_otp_write(void *opaque, hwaddr addr, 99 uint64_t val64, unsigned int size) 100 { 101 SiFiveUOTPState *s = opaque; 102 uint32_t val32 = (uint32_t)val64; 103 104 switch (addr) { 105 case SIFIVE_U_OTP_PA: 106 s->pa = val32 & SIFIVE_U_OTP_PA_MASK; 107 break; 108 case SIFIVE_U_OTP_PAIO: 109 s->paio = val32; 110 break; 111 case SIFIVE_U_OTP_PAS: 112 s->pas = val32; 113 break; 114 case SIFIVE_U_OTP_PCE: 115 s->pce = val32; 116 break; 117 case SIFIVE_U_OTP_PCLK: 118 s->pclk = val32; 119 break; 120 case SIFIVE_U_OTP_PDIN: 121 s->pdin = val32; 122 break; 123 case SIFIVE_U_OTP_PDOUT: 124 /* read-only */ 125 break; 126 case SIFIVE_U_OTP_PDSTB: 127 s->pdstb = val32; 128 break; 129 case SIFIVE_U_OTP_PPROG: 130 s->pprog = val32; 131 break; 132 case SIFIVE_U_OTP_PTC: 133 s->ptc = val32; 134 break; 135 case SIFIVE_U_OTP_PTM: 136 s->ptm = val32; 137 break; 138 case SIFIVE_U_OTP_PTM_REP: 139 s->ptm_rep = val32; 140 break; 141 case SIFIVE_U_OTP_PTR: 142 s->ptr = val32; 143 break; 144 case SIFIVE_U_OTP_PTRIM: 145 s->ptrim = val32; 146 break; 147 case SIFIVE_U_OTP_PWE: 148 s->pwe = val32 & SIFIVE_U_OTP_PWE_EN; 149 150 /* PWE is enabled. Ignore PAS=1 (no redundancy cell) */ 151 if (s->pwe && !s->pas) { 152 if (GET_FUSEARRAY_BIT(s->fuse_wo, s->pa, s->paio)) { 153 qemu_log_mask(LOG_GUEST_ERROR, 154 "write once error: idx<%u>, bit<%u>\n", 155 s->pa, s->paio); 156 break; 157 } 158 159 /* write bit data */ 160 SET_FUSEARRAY_BIT(s->fuse, s->pa, s->paio, s->pdin); 161 162 /* write to backend */ 163 if (s->blk) { 164 blk_pwrite(s->blk, s->pa * SIFIVE_U_OTP_FUSE_WORD, 165 &s->fuse[s->pa], SIFIVE_U_OTP_FUSE_WORD, 0); 166 } 167 168 /* update written bit */ 169 SET_FUSEARRAY_BIT(s->fuse_wo, s->pa, s->paio, WRITTEN_BIT_ON); 170 } 171 172 break; 173 default: 174 qemu_log_mask(LOG_GUEST_ERROR, "%s: bad write: addr=0x%" HWADDR_PRIx 175 " v=0x%x\n", __func__, addr, val32); 176 } 177 } 178 179 static const MemoryRegionOps sifive_u_otp_ops = { 180 .read = sifive_u_otp_read, 181 .write = sifive_u_otp_write, 182 .endianness = DEVICE_NATIVE_ENDIAN, 183 .valid = { 184 .min_access_size = 4, 185 .max_access_size = 4 186 } 187 }; 188 189 static Property sifive_u_otp_properties[] = { 190 DEFINE_PROP_UINT32("serial", SiFiveUOTPState, serial, 0), 191 DEFINE_PROP_DRIVE("drive", SiFiveUOTPState, blk), 192 DEFINE_PROP_END_OF_LIST(), 193 }; 194 195 static void sifive_u_otp_realize(DeviceState *dev, Error **errp) 196 { 197 SiFiveUOTPState *s = SIFIVE_U_OTP(dev); 198 DriveInfo *dinfo; 199 200 memory_region_init_io(&s->mmio, OBJECT(dev), &sifive_u_otp_ops, s, 201 TYPE_SIFIVE_U_OTP, SIFIVE_U_OTP_REG_SIZE); 202 sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio); 203 204 dinfo = drive_get_next(IF_NONE); 205 if (dinfo) { 206 int ret; 207 uint64_t perm; 208 int filesize; 209 BlockBackend *blk; 210 211 blk = blk_by_legacy_dinfo(dinfo); 212 filesize = SIFIVE_U_OTP_NUM_FUSES * SIFIVE_U_OTP_FUSE_WORD; 213 if (blk_getlength(blk) < filesize) { 214 error_setg(errp, "OTP drive size < 16K"); 215 return; 216 } 217 218 qdev_prop_set_drive_err(dev, "drive", blk, errp); 219 220 if (s->blk) { 221 perm = BLK_PERM_CONSISTENT_READ | 222 (blk_is_read_only(s->blk) ? 0 : BLK_PERM_WRITE); 223 ret = blk_set_perm(s->blk, perm, BLK_PERM_ALL, errp); 224 if (ret < 0) { 225 return; 226 } 227 228 if (blk_pread(s->blk, 0, s->fuse, filesize) != filesize) { 229 error_setg(errp, "failed to read the initial flash content"); 230 } 231 } 232 } 233 } 234 235 static void sifive_u_otp_reset(DeviceState *dev) 236 { 237 SiFiveUOTPState *s = SIFIVE_U_OTP(dev); 238 239 /* Initialize all fuses' initial value to 0xFFs */ 240 memset(s->fuse, 0xff, sizeof(s->fuse)); 241 242 /* Make a valid content of serial number */ 243 s->fuse[SIFIVE_U_OTP_SERIAL_ADDR] = s->serial; 244 s->fuse[SIFIVE_U_OTP_SERIAL_ADDR + 1] = ~(s->serial); 245 246 if (s->blk) { 247 /* Put serial number to backend as well*/ 248 uint32_t serial_data; 249 int index = SIFIVE_U_OTP_SERIAL_ADDR; 250 251 serial_data = s->serial; 252 blk_pwrite(s->blk, index * SIFIVE_U_OTP_FUSE_WORD, 253 &serial_data, SIFIVE_U_OTP_FUSE_WORD, 0); 254 255 serial_data = ~(s->serial); 256 blk_pwrite(s->blk, (index + 1) * SIFIVE_U_OTP_FUSE_WORD, 257 &serial_data, SIFIVE_U_OTP_FUSE_WORD, 0); 258 } 259 260 /* Initialize write-once map */ 261 memset(s->fuse_wo, 0x00, sizeof(s->fuse_wo)); 262 } 263 264 static void sifive_u_otp_class_init(ObjectClass *klass, void *data) 265 { 266 DeviceClass *dc = DEVICE_CLASS(klass); 267 268 device_class_set_props(dc, sifive_u_otp_properties); 269 dc->realize = sifive_u_otp_realize; 270 dc->reset = sifive_u_otp_reset; 271 } 272 273 static const TypeInfo sifive_u_otp_info = { 274 .name = TYPE_SIFIVE_U_OTP, 275 .parent = TYPE_SYS_BUS_DEVICE, 276 .instance_size = sizeof(SiFiveUOTPState), 277 .class_init = sifive_u_otp_class_init, 278 }; 279 280 static void sifive_u_otp_register_types(void) 281 { 282 type_register_static(&sifive_u_otp_info); 283 } 284 285 type_init(sifive_u_otp_register_types) 286