1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (C) 2009-2012 Semihalf 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 /* Simulated NAND controller driver */ 30 31 #include <sys/cdefs.h> 32 __FBSDID("$FreeBSD$"); 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/proc.h> 37 #include <sys/bus.h> 38 #include <sys/conf.h> 39 #include <sys/kernel.h> 40 #include <sys/module.h> 41 #include <sys/rman.h> 42 #include <sys/lock.h> 43 #include <sys/mutex.h> 44 #include <sys/time.h> 45 46 #include <dev/nand/nand.h> 47 #include <dev/nand/nandbus.h> 48 #include <dev/nand/nandsim.h> 49 #include <dev/nand/nandsim_log.h> 50 #include <dev/nand/nandsim_chip.h> 51 #include "nfc_if.h" 52 53 #define ADDRESS_SIZE 5 54 55 extern struct sim_ctrl_conf ctrls[MAX_SIM_DEV]; 56 57 static void byte_corrupt(struct nandsim_chip *, uint8_t *); 58 59 static int nandsim_attach(device_t); 60 static int nandsim_detach(device_t); 61 static int nandsim_probe(device_t); 62 63 static uint8_t nandsim_read_byte(device_t); 64 static uint16_t nandsim_read_word(device_t); 65 static int nandsim_select_cs(device_t, uint8_t); 66 static void nandsim_write_byte(device_t, uint8_t); 67 static void nandsim_write_word(device_t, uint16_t); 68 static void nandsim_read_buf(device_t, void *, uint32_t); 69 static void nandsim_write_buf(device_t, void *, uint32_t); 70 static int nandsim_send_command(device_t, uint8_t); 71 static int nandsim_send_address(device_t, uint8_t); 72 73 static device_method_t nandsim_methods[] = { 74 DEVMETHOD(device_probe, nandsim_probe), 75 DEVMETHOD(device_attach, nandsim_attach), 76 DEVMETHOD(device_detach, nandsim_detach), 77 78 DEVMETHOD(nfc_select_cs, nandsim_select_cs), 79 DEVMETHOD(nfc_send_command, nandsim_send_command), 80 DEVMETHOD(nfc_send_address, nandsim_send_address), 81 DEVMETHOD(nfc_read_byte, nandsim_read_byte), 82 DEVMETHOD(nfc_read_word, nandsim_read_word), 83 DEVMETHOD(nfc_write_byte, nandsim_write_byte), 84 DEVMETHOD(nfc_read_buf, nandsim_read_buf), 85 DEVMETHOD(nfc_write_buf, nandsim_write_buf), 86 87 { 0, 0 }, 88 }; 89 90 static driver_t nandsim_driver = { 91 "nandsim", 92 nandsim_methods, 93 sizeof(struct nandsim_softc), 94 }; 95 96 static devclass_t nandsim_devclass; 97 DRIVER_MODULE(nandsim, nexus, nandsim_driver, nandsim_devclass, 0, 0); 98 DRIVER_MODULE(nandbus, nandsim, nandbus_driver, nandbus_devclass, 0, 0); 99 100 static int 101 nandsim_probe(device_t dev) 102 { 103 104 device_set_desc(dev, "NAND controller simulator"); 105 return (BUS_PROBE_DEFAULT); 106 } 107 108 static int 109 nandsim_attach(device_t dev) 110 { 111 struct nandsim_softc *sc; 112 struct sim_ctrl_conf *params; 113 struct sim_chip *chip; 114 uint16_t *eccpos; 115 int i, err; 116 117 sc = device_get_softc(dev); 118 params = &ctrls[device_get_unit(dev)]; 119 120 if (strlen(params->filename) == 0) 121 snprintf(params->filename, FILENAME_SIZE, "ctrl%d.log", 122 params->num); 123 124 nandsim_log_init(sc, params->filename); 125 for (i = 0; i < params->num_cs; i++) { 126 chip = params->chips[i]; 127 if (chip && chip->device_id != 0) { 128 sc->chips[i] = nandsim_chip_init(sc, i, chip); 129 if (chip->features & ONFI_FEAT_16BIT) 130 sc->nand_dev.flags |= NAND_16_BIT; 131 } 132 } 133 134 if (params->ecc_layout[0] != 0xffff) 135 eccpos = params->ecc_layout; 136 else 137 eccpos = NULL; 138 139 nand_init(&sc->nand_dev, dev, params->ecc, 0, 0, eccpos, "nandsim"); 140 141 err = nandbus_create(dev); 142 143 return (err); 144 } 145 146 static int 147 nandsim_detach(device_t dev) 148 { 149 struct nandsim_softc *sc; 150 struct sim_ctrl_conf *params; 151 int i; 152 153 sc = device_get_softc(dev); 154 params = &ctrls[device_get_unit(dev)]; 155 156 for (i = 0; i < params->num_cs; i++) 157 if (sc->chips[i] != NULL) 158 nandsim_chip_destroy(sc->chips[i]); 159 160 nandsim_log_close(sc); 161 162 return (0); 163 } 164 165 static int 166 nandsim_select_cs(device_t dev, uint8_t cs) 167 { 168 struct nandsim_softc *sc; 169 170 sc = device_get_softc(dev); 171 172 if (cs >= MAX_CS_NUM) 173 return (EINVAL); 174 175 sc->active_chip = sc->chips[cs]; 176 177 if (sc->active_chip) 178 nandsim_log(sc->active_chip, NANDSIM_LOG_EV, 179 "Select cs %d\n", cs); 180 181 return (0); 182 } 183 184 static int 185 nandsim_send_command(device_t dev, uint8_t command) 186 { 187 struct nandsim_softc *sc; 188 struct nandsim_chip *chip; 189 struct nandsim_ev *ev; 190 191 sc = device_get_softc(dev); 192 chip = sc->active_chip; 193 194 if (chip == NULL) 195 return (0); 196 197 nandsim_log(chip, NANDSIM_LOG_EV, "Send command %x\n", command); 198 199 switch (command) { 200 case NAND_CMD_READ_ID: 201 case NAND_CMD_READ_PARAMETER: 202 sc->address_type = ADDR_ID; 203 break; 204 case NAND_CMD_ERASE: 205 sc->address_type = ADDR_ROW; 206 break; 207 case NAND_CMD_READ: 208 case NAND_CMD_PROG: 209 sc->address_type = ADDR_ROWCOL; 210 break; 211 default: 212 sc->address_type = ADDR_NONE; 213 break; 214 } 215 216 if (command == NAND_CMD_STATUS) 217 chip->flags |= NANDSIM_CHIP_GET_STATUS; 218 else { 219 ev = create_event(chip, NANDSIM_EV_CMD, 1); 220 *(uint8_t *)ev->data = command; 221 send_event(ev); 222 } 223 224 return (0); 225 } 226 227 static int 228 nandsim_send_address(device_t dev, uint8_t addr) 229 { 230 struct nandsim_ev *ev; 231 struct nandsim_softc *sc; 232 struct nandsim_chip *chip; 233 234 sc = device_get_softc(dev); 235 chip = sc->active_chip; 236 237 if (chip == NULL) 238 return (0); 239 240 KASSERT((sc->address_type != ADDR_NONE), ("unexpected address")); 241 nandsim_log(chip, NANDSIM_LOG_EV, "Send addr %x\n", addr); 242 243 ev = create_event(chip, NANDSIM_EV_ADDR, 1); 244 245 *((uint8_t *)(ev->data)) = addr; 246 247 send_event(ev); 248 return (0); 249 } 250 251 static uint8_t 252 nandsim_read_byte(device_t dev) 253 { 254 struct nandsim_softc *sc; 255 struct nandsim_chip *chip; 256 uint8_t ret = 0xff; 257 258 sc = device_get_softc(dev); 259 chip = sc->active_chip; 260 261 if (chip && !(chip->flags & NANDSIM_CHIP_FROZEN)) { 262 if (chip->flags & NANDSIM_CHIP_GET_STATUS) { 263 nandsim_chip_timeout(chip); 264 ret = nandchip_get_status(chip); 265 chip->flags &= ~NANDSIM_CHIP_GET_STATUS; 266 } else if (chip->data.index < chip->data.size) { 267 ret = chip->data.data_ptr[chip->data.index++]; 268 byte_corrupt(chip, &ret); 269 } 270 nandsim_log(chip, NANDSIM_LOG_DATA, "read %02x\n", ret); 271 } 272 273 return (ret); 274 } 275 276 static uint16_t 277 nandsim_read_word(device_t dev) 278 { 279 struct nandsim_softc *sc; 280 struct nandsim_chip *chip; 281 uint16_t *data_ptr; 282 uint16_t ret = 0xffff; 283 uint8_t *byte_ret = (uint8_t *)&ret; 284 285 sc = device_get_softc(dev); 286 chip = sc->active_chip; 287 288 if (chip && !(chip->flags & NANDSIM_CHIP_FROZEN)) { 289 if (chip->data.index < chip->data.size - 1) { 290 data_ptr = 291 (uint16_t *)&(chip->data.data_ptr[chip->data.index]); 292 ret = *data_ptr; 293 chip->data.index += 2; 294 byte_corrupt(chip, byte_ret); 295 byte_corrupt(chip, byte_ret + 1); 296 } 297 nandsim_log(chip, NANDSIM_LOG_DATA, "read %04x\n", ret); 298 } 299 300 return (ret); 301 } 302 303 static void 304 nandsim_write_byte(device_t dev, uint8_t byte) 305 { 306 struct nandsim_softc *sc; 307 struct nandsim_chip *chip; 308 309 sc = device_get_softc(dev); 310 chip = sc->active_chip; 311 312 if (chip && !(chip->flags & NANDSIM_CHIP_FROZEN) && 313 (chip->data.index < chip->data.size)) { 314 byte_corrupt(chip, &byte); 315 chip->data.data_ptr[chip->data.index] &= byte; 316 chip->data.index++; 317 nandsim_log(chip, NANDSIM_LOG_DATA, "write %02x\n", byte); 318 } 319 } 320 321 static void 322 nandsim_write_word(device_t dev, uint16_t word) 323 { 324 struct nandsim_softc *sc; 325 struct nandsim_chip *chip; 326 uint16_t *data_ptr; 327 uint8_t *byte_ptr = (uint8_t *)&word; 328 329 sc = device_get_softc(dev); 330 chip = sc->active_chip; 331 332 if (chip && !(chip->flags & NANDSIM_CHIP_FROZEN)) { 333 if ((chip->data.index + 1) < chip->data.size) { 334 byte_corrupt(chip, byte_ptr); 335 byte_corrupt(chip, byte_ptr + 1); 336 data_ptr = 337 (uint16_t *)&(chip->data.data_ptr[chip->data.index]); 338 *data_ptr &= word; 339 chip->data.index += 2; 340 } 341 342 nandsim_log(chip, NANDSIM_LOG_DATA, "write %04x\n", word); 343 } 344 } 345 346 static void 347 nandsim_read_buf(device_t dev, void *buf, uint32_t len) 348 { 349 struct nandsim_softc *sc; 350 uint16_t *buf16 = (uint16_t *)buf; 351 uint8_t *buf8 = (uint8_t *)buf; 352 int i; 353 354 sc = device_get_softc(dev); 355 356 if (sc->nand_dev.flags & NAND_16_BIT) { 357 for (i = 0; i < len / 2; i++) 358 buf16[i] = nandsim_read_word(dev); 359 } else { 360 for (i = 0; i < len; i++) 361 buf8[i] = nandsim_read_byte(dev); 362 } 363 } 364 365 static void 366 nandsim_write_buf(device_t dev, void *buf, uint32_t len) 367 { 368 struct nandsim_softc *sc; 369 uint16_t *buf16 = (uint16_t *)buf; 370 uint8_t *buf8 = (uint8_t *)buf; 371 int i; 372 373 sc = device_get_softc(dev); 374 375 if (sc->nand_dev.flags & NAND_16_BIT) { 376 for (i = 0; i < len / 2; i++) 377 nandsim_write_word(dev, buf16[i]); 378 } else { 379 for (i = 0; i < len; i++) 380 nandsim_write_byte(dev, buf8[i]); 381 } 382 } 383 384 static void 385 byte_corrupt(struct nandsim_chip *chip, uint8_t *byte) 386 { 387 uint32_t rand; 388 uint8_t bit; 389 390 rand = random(); 391 if ((rand % 1000000) < chip->error_ratio) { 392 bit = rand % 8; 393 if (*byte & (1 << bit)) 394 *byte &= ~(1 << bit); 395 else 396 *byte |= (1 << bit); 397 } 398 } 399