1 1.10 riastrad /* $NetBSD: nandemulator.c,v 1.10 2023/05/10 00:11:16 riastradh Exp $ */ 2 1.1 ahoka 3 1.1 ahoka /*- 4 1.1 ahoka * Copyright (c) 2011 Department of Software Engineering, 5 1.1 ahoka * University of Szeged, Hungary 6 1.1 ahoka * Copyright (c) 2011 Adam Hoka <ahoka (at) NetBSD.org> 7 1.1 ahoka * All rights reserved. 8 1.1 ahoka * 9 1.1 ahoka * This code is derived from software contributed to The NetBSD Foundation 10 1.1 ahoka * by the Department of Software Engineering, University of Szeged, Hungary 11 1.1 ahoka * 12 1.1 ahoka * Redistribution and use in source and binary forms, with or without 13 1.1 ahoka * modification, are permitted provided that the following conditions 14 1.1 ahoka * are met: 15 1.1 ahoka * 1. Redistributions of source code must retain the above copyright 16 1.1 ahoka * notice, this list of conditions and the following disclaimer. 17 1.1 ahoka * 2. Redistributions in binary form must reproduce the above copyright 18 1.1 ahoka * notice, this list of conditions and the following disclaimer in the 19 1.1 ahoka * documentation and/or other materials provided with the distribution. 20 1.1 ahoka * 21 1.1 ahoka * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 1.1 ahoka * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 1.1 ahoka * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 1.1 ahoka * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 1.1 ahoka * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 1.1 ahoka * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 1.1 ahoka * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 1.1 ahoka * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 1.1 ahoka * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 1.1 ahoka * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 1.1 ahoka * SUCH DAMAGE. 32 1.1 ahoka */ 33 1.1 ahoka 34 1.1 ahoka #include <sys/cdefs.h> 35 1.10 riastrad __KERNEL_RCSID(0, "$NetBSD: nandemulator.c,v 1.10 2023/05/10 00:11:16 riastradh Exp $"); 36 1.8 mrg 37 1.8 mrg /* XXX this code likely needs work */ 38 1.1 ahoka 39 1.1 ahoka #include <sys/param.h> 40 1.1 ahoka #include <sys/device.h> 41 1.1 ahoka #include <sys/conf.h> 42 1.1 ahoka #include <sys/kmem.h> 43 1.1 ahoka #include <sys/kernel.h> 44 1.1 ahoka 45 1.1 ahoka #include "nandemulator.h" 46 1.1 ahoka 47 1.1 ahoka #include <dev/nand/nand.h> 48 1.1 ahoka #include <dev/nand/onfi.h> 49 1.1 ahoka #include <dev/nand/nand_crc.h> 50 1.1 ahoka 51 1.7 christos #include "ioconf.h" 52 1.7 christos 53 1.1 ahoka extern struct cfdriver nandemulator_cd; 54 1.1 ahoka 55 1.1 ahoka static int nandemulator_match(device_t, cfdata_t, void *); 56 1.1 ahoka static void nandemulator_attach(device_t, device_t, void *); 57 1.1 ahoka static int nandemulator_detach(device_t, int); 58 1.1 ahoka 59 1.1 ahoka static void nandemulator_device_reset(device_t); 60 1.1 ahoka static void nandemulator_command(device_t, uint8_t); 61 1.1 ahoka static void nandemulator_address(device_t, uint8_t); 62 1.1 ahoka static void nandemulator_busy(device_t); 63 1.5 ahoka static void nandemulator_read_1(device_t, uint8_t *); 64 1.5 ahoka static void nandemulator_write_1(device_t, uint8_t); 65 1.5 ahoka static void nandemulator_read_2(device_t, uint16_t *); 66 1.5 ahoka static void nandemulator_write_2(device_t, uint16_t); 67 1.5 ahoka static void nandemulator_read_buf_1(device_t, void *, size_t); 68 1.5 ahoka static void nandemulator_read_buf_2(device_t, void *, size_t); 69 1.5 ahoka static void nandemulator_write_buf_1(device_t, const void *, size_t); 70 1.5 ahoka static void nandemulator_write_buf_2(device_t, const void *, size_t); 71 1.1 ahoka 72 1.1 ahoka static size_t nandemulator_address_to_page(device_t); 73 1.1 ahoka static size_t nandemulator_page_to_backend_offset(device_t, size_t); 74 1.1 ahoka static size_t nandemulator_column_address_to_subpage(device_t); 75 1.1 ahoka /* 76 1.1 ahoka #define NANDEMULATOR_DEBUG 1 77 1.1 ahoka 78 1.1 ahoka #ifdef NANDEMULATOR_DEBUG 79 1.1 ahoka #warning debug enabled 80 1.1 ahoka #define DPRINTF(x) if (nandemulatordebug) printf x 81 1.1 ahoka #define DPRINTFN(n,x) if (nandemulatordebug>(n)) printf x 82 1.1 ahoka #else 83 1.1 ahoka #error no debug 84 1.1 ahoka #define DPRINTF(x) 85 1.1 ahoka #define DPRINTFN(n,x) 86 1.1 ahoka #endif 87 1.1 ahoka 88 1.1 ahoka #ifdef NANDEMULATOR_DEBUG 89 1.1 ahoka int nandemulatordebug = NANDEMULATOR_DEBUG; 90 1.1 ahoka #endif 91 1.1 ahoka */ 92 1.1 ahoka 93 1.1 ahoka extern int nanddebug; 94 1.1 ahoka 95 1.1 ahoka enum { 96 1.1 ahoka NANDEMULATOR_8BIT, 97 1.1 ahoka NANDEMULATOR_16BIT 98 1.1 ahoka }; 99 1.1 ahoka 100 1.1 ahoka struct nandemulator_softc { 101 1.1 ahoka device_t sc_dev; 102 1.1 ahoka device_t sc_nanddev; 103 1.1 ahoka 104 1.1 ahoka int sc_buswidth; 105 1.1 ahoka 106 1.1 ahoka struct nand_interface sc_nand_if; 107 1.1 ahoka 108 1.1 ahoka uint8_t sc_command; 109 1.1 ahoka size_t sc_io_len; 110 1.1 ahoka uint8_t *sc_io_pointer; 111 1.1 ahoka uint64_t sc_address; 112 1.1 ahoka 113 1.1 ahoka uint8_t *sc_backend; 114 1.1 ahoka size_t sc_backend_size; 115 1.1 ahoka size_t sc_device_size; 116 1.1 ahoka bool sc_register_writable; 117 1.1 ahoka 118 1.1 ahoka uint8_t sc_status_register; 119 1.1 ahoka uint8_t sc_ids[2]; 120 1.1 ahoka uint8_t sc_onfi[4]; 121 1.1 ahoka 122 1.1 ahoka size_t sc_page_size; 123 1.1 ahoka size_t sc_block_size; 124 1.1 ahoka size_t sc_spare_size; 125 1.1 ahoka size_t sc_lun_size; 126 1.1 ahoka uint8_t sc_row_cycles; 127 1.1 ahoka uint8_t sc_column_cycles; 128 1.1 ahoka uint64_t sc_row_mask; 129 1.1 ahoka 130 1.1 ahoka int sc_address_counter; 131 1.1 ahoka 132 1.1 ahoka struct onfi_parameter_page *sc_parameter_page; 133 1.1 ahoka }; 134 1.1 ahoka 135 1.1 ahoka CFATTACH_DECL_NEW(nandemulator, sizeof(struct nandemulator_softc), 136 1.1 ahoka nandemulator_match, nandemulator_attach, nandemulator_detach, NULL); 137 1.1 ahoka 138 1.1 ahoka void 139 1.1 ahoka nandemulatorattach(int n) 140 1.1 ahoka { 141 1.1 ahoka int i, err; 142 1.1 ahoka cfdata_t cf; 143 1.1 ahoka 144 1.1 ahoka aprint_debug("nandemulator: requested %d units\n", n); 145 1.1 ahoka 146 1.1 ahoka err = config_cfattach_attach(nandemulator_cd.cd_name, 147 1.1 ahoka &nandemulator_ca); 148 1.1 ahoka if (err) { 149 1.1 ahoka aprint_error("%s: couldn't register cfattach: %d\n", 150 1.1 ahoka nandemulator_cd.cd_name, err); 151 1.1 ahoka config_cfdriver_detach(&nandemulator_cd); 152 1.1 ahoka return; 153 1.1 ahoka } 154 1.1 ahoka for (i = 0; i < n; i++) { 155 1.9 chs cf = kmem_alloc(sizeof(struct cfdata), KM_SLEEP); 156 1.1 ahoka cf->cf_name = nandemulator_cd.cd_name; 157 1.1 ahoka cf->cf_atname = nandemulator_cd.cd_name; 158 1.1 ahoka cf->cf_unit = i; 159 1.1 ahoka cf->cf_fstate = FSTATE_STAR; 160 1.1 ahoka 161 1.1 ahoka (void)config_attach_pseudo(cf); 162 1.1 ahoka } 163 1.1 ahoka } 164 1.1 ahoka 165 1.1 ahoka /* ARGSUSED */ 166 1.1 ahoka static int 167 1.1 ahoka nandemulator_match(device_t parent, cfdata_t match, void *aux) 168 1.1 ahoka { 169 1.1 ahoka /* pseudo device, always attaches */ 170 1.1 ahoka return 1; 171 1.1 ahoka } 172 1.1 ahoka 173 1.1 ahoka static void 174 1.1 ahoka nandemulator_attach(device_t parent, device_t self, void *aux) 175 1.1 ahoka { 176 1.1 ahoka struct nandemulator_softc *sc = device_private(self); 177 1.1 ahoka int i; 178 1.1 ahoka 179 1.1 ahoka aprint_normal_dev(self, "NAND emulator\n"); 180 1.1 ahoka 181 1.1 ahoka sc->sc_dev = self; 182 1.1 ahoka 183 1.2 ahoka nand_init_interface(&sc->sc_nand_if); 184 1.2 ahoka 185 1.1 ahoka sc->sc_nand_if.command = &nandemulator_command; 186 1.1 ahoka sc->sc_nand_if.address = &nandemulator_address; 187 1.5 ahoka sc->sc_nand_if.read_buf_1 = &nandemulator_read_buf_1; 188 1.5 ahoka sc->sc_nand_if.read_buf_2 = &nandemulator_read_buf_2; 189 1.5 ahoka sc->sc_nand_if.read_1 = &nandemulator_read_1; 190 1.5 ahoka sc->sc_nand_if.read_2 = &nandemulator_read_2; 191 1.5 ahoka sc->sc_nand_if.write_buf_1 = &nandemulator_write_buf_1; 192 1.5 ahoka sc->sc_nand_if.write_buf_2 = &nandemulator_write_buf_2; 193 1.5 ahoka sc->sc_nand_if.write_1 = &nandemulator_write_1; 194 1.5 ahoka sc->sc_nand_if.write_2 = &nandemulator_write_2; 195 1.1 ahoka sc->sc_nand_if.busy = &nandemulator_busy; 196 1.1 ahoka 197 1.1 ahoka sc->sc_nand_if.ecc.necc_code_size = 3; 198 1.1 ahoka sc->sc_nand_if.ecc.necc_block_size = 256; 199 1.1 ahoka 200 1.1 ahoka if (!pmf_device_register1(sc->sc_dev, NULL, NULL, NULL)) 201 1.1 ahoka aprint_error_dev(sc->sc_dev, 202 1.1 ahoka "couldn't establish power handler\n"); 203 1.1 ahoka 204 1.1 ahoka sc->sc_buswidth = NANDEMULATOR_16BIT; /* 16bit for now */ 205 1.1 ahoka 206 1.1 ahoka /* hardcode these now, make it configurable later */ 207 1.1 ahoka sc->sc_device_size = 32 * 1024 * 1024; /* 32MB */ 208 1.1 ahoka sc->sc_page_size = 2048; 209 1.1 ahoka sc->sc_block_size = 64; 210 1.1 ahoka sc->sc_lun_size = 211 1.1 ahoka sc->sc_device_size / (sc->sc_page_size * sc->sc_block_size); 212 1.1 ahoka KASSERT(sc->sc_device_size % 213 1.1 ahoka (sc->sc_page_size * sc->sc_block_size) == 0); 214 1.1 ahoka sc->sc_spare_size = 64; 215 1.1 ahoka 216 1.1 ahoka sc->sc_column_cycles = 2; 217 1.1 ahoka sc->sc_row_cycles = 3; 218 1.1 ahoka 219 1.1 ahoka /* init the emulator data structures */ 220 1.1 ahoka sc->sc_backend_size = 221 1.1 ahoka sc->sc_device_size + 222 1.1 ahoka sc->sc_device_size / sc->sc_page_size * sc->sc_spare_size; 223 1.1 ahoka 224 1.1 ahoka sc->sc_backend = kmem_alloc(sc->sc_backend_size, KM_SLEEP); 225 1.1 ahoka memset(sc->sc_backend, 0xff, sc->sc_backend_size); 226 1.1 ahoka 227 1.1 ahoka sc->sc_parameter_page = 228 1.1 ahoka kmem_zalloc(sizeof(struct onfi_parameter_page) * 4, KM_SLEEP); 229 1.1 ahoka 230 1.1 ahoka struct onfi_parameter_page *opp; 231 1.1 ahoka uint8_t sig[4] = { 'O', 'N', 'F', 'I' }; 232 1.1 ahoka 233 1.1 ahoka for (i = 0; i < 4; i++) { 234 1.1 ahoka opp = &sc->sc_parameter_page[i]; 235 1.1 ahoka 236 1.6 ahoka opp->param_signature = htole32(*(uint32_t *)sig); 237 1.6 ahoka opp->param_pagesize = htole32(sc->sc_page_size); 238 1.6 ahoka opp->param_blocksize = htole32(sc->sc_block_size); 239 1.6 ahoka opp->param_sparesize = htole16(sc->sc_spare_size); 240 1.6 ahoka opp->param_lunsize = htole32(sc->sc_lun_size); 241 1.1 ahoka opp->param_numluns = 1; 242 1.1 ahoka 243 1.1 ahoka opp->param_manufacturer_id = 0x00; 244 1.1 ahoka memcpy(opp->param_manufacturer, 245 1.1 ahoka "NETBSD", strlen("NETBSD")); 246 1.1 ahoka memcpy(opp->param_model, 247 1.1 ahoka "NANDEMULATOR", strlen("NANDEMULATOR")); 248 1.1 ahoka 249 1.6 ahoka uint16_t features = ONFI_FEATURE_16BIT; 250 1.6 ahoka opp->param_features = htole16(features); 251 1.1 ahoka 252 1.1 ahoka /* the lower 4 bits contain the row address cycles 253 1.1 ahoka * the upper 4 bits contain the column address cycles 254 1.1 ahoka */ 255 1.1 ahoka opp->param_addr_cycles = sc->sc_row_cycles; 256 1.1 ahoka opp->param_addr_cycles |= (sc->sc_column_cycles << 4); 257 1.1 ahoka 258 1.1 ahoka opp->param_integrity_crc = nand_crc16((uint8_t *)opp, 254); 259 1.1 ahoka } 260 1.1 ahoka 261 1.1 ahoka sc->sc_ids[0] = 0x00; 262 1.1 ahoka sc->sc_ids[1] = 0x00; 263 1.1 ahoka 264 1.1 ahoka sc->sc_onfi[0] = 'O'; 265 1.1 ahoka sc->sc_onfi[1] = 'N'; 266 1.1 ahoka sc->sc_onfi[2] = 'F'; 267 1.1 ahoka sc->sc_onfi[3] = 'I'; 268 1.1 ahoka 269 1.1 ahoka sc->sc_row_mask = 0x00; 270 1.1 ahoka for (i = 0; i < sc->sc_row_cycles; i++) { 271 1.1 ahoka sc->sc_row_mask <<= 8; 272 1.1 ahoka sc->sc_row_mask |= 0xff; 273 1.1 ahoka } 274 1.1 ahoka 275 1.1 ahoka nandemulator_device_reset(self); 276 1.1 ahoka 277 1.1 ahoka sc->sc_nanddev = nand_attach_mi(&sc->sc_nand_if, sc->sc_dev); 278 1.1 ahoka } 279 1.1 ahoka 280 1.1 ahoka static int 281 1.1 ahoka nandemulator_detach(device_t self, int flags) 282 1.1 ahoka { 283 1.1 ahoka struct nandemulator_softc *sc = device_private(self); 284 1.10 riastrad int error; 285 1.1 ahoka 286 1.1 ahoka aprint_normal_dev(sc->sc_dev, "detaching emulator\n"); 287 1.1 ahoka 288 1.10 riastrad error = config_detach_children(self, flags); 289 1.10 riastrad if (error) 290 1.10 riastrad return error; 291 1.10 riastrad 292 1.1 ahoka pmf_device_deregister(sc->sc_dev); 293 1.1 ahoka kmem_free(sc->sc_backend, sc->sc_backend_size); 294 1.1 ahoka kmem_free(sc->sc_parameter_page, 295 1.1 ahoka sizeof(struct onfi_parameter_page) * 4); 296 1.10 riastrad return 0; 297 1.1 ahoka } 298 1.1 ahoka 299 1.1 ahoka /** 300 1.1 ahoka * bring the emulated device to a known state 301 1.1 ahoka */ 302 1.1 ahoka static void 303 1.1 ahoka nandemulator_device_reset(device_t self) 304 1.1 ahoka { 305 1.1 ahoka struct nandemulator_softc *sc = device_private(self); 306 1.1 ahoka 307 1.3 ahoka DPRINTF(("device reset\n")); 308 1.3 ahoka 309 1.1 ahoka sc->sc_command = 0; 310 1.1 ahoka sc->sc_register_writable = false; 311 1.1 ahoka sc->sc_io_len = 0; 312 1.1 ahoka sc->sc_io_pointer = NULL; 313 1.1 ahoka sc->sc_address = 0; 314 1.1 ahoka sc->sc_address_counter = 0; 315 1.1 ahoka 316 1.1 ahoka sc->sc_status_register = ONFI_STATUS_RDY | ONFI_STATUS_WP; 317 1.1 ahoka } 318 1.1 ahoka 319 1.1 ahoka static void 320 1.1 ahoka nandemulator_address_chip(device_t self) 321 1.1 ahoka { 322 1.1 ahoka struct nandemulator_softc *sc = device_private(self); 323 1.1 ahoka size_t page, offset; 324 1.3 ahoka 325 1.3 ahoka KASSERT(sc->sc_address_counter == 326 1.3 ahoka sc->sc_column_cycles + sc->sc_row_cycles); 327 1.5 ahoka 328 1.1 ahoka if (sc->sc_address_counter != 329 1.1 ahoka sc->sc_column_cycles + sc->sc_row_cycles) { 330 1.1 ahoka aprint_error_dev(self, "incorrect number of address cycles\n"); 331 1.1 ahoka aprint_error_dev(self, "cc: %d, rc: %d, ac: %d\n", 332 1.1 ahoka sc->sc_column_cycles, sc->sc_row_cycles, 333 1.1 ahoka sc->sc_address_counter); 334 1.1 ahoka } 335 1.1 ahoka 336 1.1 ahoka page = nandemulator_address_to_page(self); 337 1.1 ahoka offset = sc->sc_page_size * page; 338 1.1 ahoka 339 1.1 ahoka DPRINTF(("READ/PROGRAM; page: 0x%jx (row addr: 0x%jx)\n", 340 1.1 ahoka (uintmax_t )page, 341 1.1 ahoka (uintmax_t )offset)); 342 1.1 ahoka 343 1.3 ahoka KASSERT(offset < sc->sc_device_size); 344 1.3 ahoka 345 1.1 ahoka if (offset >= sc->sc_device_size) { 346 1.1 ahoka aprint_error_dev(self, "address > device size!\n"); 347 1.1 ahoka sc->sc_io_len = 0; 348 1.1 ahoka } else { 349 1.1 ahoka size_t addr = 350 1.1 ahoka nandemulator_page_to_backend_offset(self, page); 351 1.1 ahoka size_t pageoff = 352 1.1 ahoka nandemulator_column_address_to_subpage(self); 353 1.1 ahoka 354 1.1 ahoka DPRINTF(("subpage: 0x%jx\n", (uintmax_t )pageoff)); 355 1.1 ahoka 356 1.1 ahoka KASSERT(pageoff < 357 1.1 ahoka sc->sc_page_size + sc->sc_spare_size); 358 1.1 ahoka KASSERT(addr < sc->sc_backend_size); 359 1.1 ahoka 360 1.1 ahoka sc->sc_io_pointer = sc->sc_backend + addr + pageoff; 361 1.1 ahoka sc->sc_io_len = 362 1.1 ahoka sc->sc_page_size + sc->sc_spare_size - pageoff; 363 1.1 ahoka } 364 1.1 ahoka } 365 1.1 ahoka 366 1.1 ahoka static void 367 1.1 ahoka nandemulator_command(device_t self, uint8_t command) 368 1.1 ahoka { 369 1.1 ahoka struct nandemulator_softc *sc = device_private(self); 370 1.1 ahoka size_t offset, page; 371 1.1 ahoka 372 1.1 ahoka sc->sc_command = command; 373 1.1 ahoka sc->sc_register_writable = false; 374 1.1 ahoka 375 1.1 ahoka DPRINTF(("nandemulator command: 0x%hhx\n", command)); 376 1.1 ahoka 377 1.1 ahoka switch (command) { 378 1.1 ahoka case ONFI_READ_STATUS: 379 1.1 ahoka sc->sc_io_pointer = &sc->sc_status_register; 380 1.1 ahoka sc->sc_io_len = 1; 381 1.1 ahoka break; 382 1.1 ahoka case ONFI_RESET: 383 1.1 ahoka nandemulator_device_reset(self); 384 1.1 ahoka break; 385 1.1 ahoka case ONFI_PAGE_PROGRAM: 386 1.1 ahoka sc->sc_register_writable = true; 387 1.8 mrg /* FALLTHROUGH */ 388 1.1 ahoka case ONFI_READ: 389 1.1 ahoka case ONFI_BLOCK_ERASE: 390 1.1 ahoka sc->sc_address_counter = 0; 391 1.8 mrg /* FALLTHROUGH */ 392 1.1 ahoka case ONFI_READ_ID: 393 1.1 ahoka case ONFI_READ_PARAMETER_PAGE: 394 1.1 ahoka sc->sc_io_len = 0; 395 1.1 ahoka sc->sc_address = 0; 396 1.1 ahoka break; 397 1.1 ahoka case ONFI_PAGE_PROGRAM_START: 398 1.1 ahoka /* XXX the program should only happen here */ 399 1.1 ahoka break; 400 1.1 ahoka case ONFI_READ_START: 401 1.1 ahoka nandemulator_address_chip(self); 402 1.1 ahoka break; 403 1.1 ahoka case ONFI_BLOCK_ERASE_START: 404 1.1 ahoka page = nandemulator_address_to_page(self); 405 1.1 ahoka offset = sc->sc_page_size * page; 406 1.1 ahoka 407 1.1 ahoka KASSERT(offset % 408 1.1 ahoka (sc->sc_block_size * sc->sc_page_size) == 0); 409 1.1 ahoka 410 1.3 ahoka KASSERT(offset < sc->sc_device_size); 411 1.3 ahoka 412 1.1 ahoka if (offset >= sc->sc_device_size) { 413 1.1 ahoka aprint_error_dev(self, "address > device size!\n"); 414 1.1 ahoka } else { 415 1.1 ahoka size_t addr = 416 1.1 ahoka nandemulator_page_to_backend_offset(self, page); 417 1.1 ahoka 418 1.1 ahoka size_t blocklen = 419 1.1 ahoka sc->sc_block_size * 420 1.1 ahoka (sc->sc_page_size + sc->sc_spare_size); 421 1.1 ahoka 422 1.1 ahoka KASSERT(addr < sc->sc_backend_size); 423 1.1 ahoka uint8_t *block = sc->sc_backend + addr; 424 1.1 ahoka 425 1.1 ahoka DPRINTF(("erasing block at 0x%jx\n", 426 1.1 ahoka (uintmax_t )offset)); 427 1.1 ahoka 428 1.1 ahoka memset(block, 0xff, blocklen); 429 1.1 ahoka } 430 1.1 ahoka sc->sc_io_len = 0; 431 1.1 ahoka break; 432 1.1 ahoka default: 433 1.1 ahoka aprint_error_dev(self, 434 1.1 ahoka "invalid nand command (0x%hhx)\n", command); 435 1.3 ahoka KASSERT(false); 436 1.1 ahoka sc->sc_io_len = 0; 437 1.1 ahoka } 438 1.1 ahoka }; 439 1.1 ahoka 440 1.1 ahoka static void 441 1.1 ahoka nandemulator_address(device_t self, uint8_t address) 442 1.1 ahoka { 443 1.1 ahoka struct nandemulator_softc *sc = device_private(self); 444 1.1 ahoka 445 1.3 ahoka DPRINTF(("nandemulator_address: %hhx\n", address)); 446 1.3 ahoka 447 1.1 ahoka /** 448 1.1 ahoka * we have to handle read id/parameter page here, 449 1.1 ahoka * as we can read right after giving the address. 450 1.1 ahoka */ 451 1.1 ahoka switch (sc->sc_command) { 452 1.1 ahoka case ONFI_READ_ID: 453 1.1 ahoka if (address == 0x00) { 454 1.1 ahoka sc->sc_io_len = 2; 455 1.1 ahoka sc->sc_io_pointer = sc->sc_ids; 456 1.1 ahoka } else if (address == 0x20) { 457 1.1 ahoka sc->sc_io_len = 4; 458 1.1 ahoka sc->sc_io_pointer = sc->sc_onfi; 459 1.1 ahoka } else { 460 1.1 ahoka sc->sc_io_len = 0; 461 1.1 ahoka } 462 1.1 ahoka break; 463 1.1 ahoka case ONFI_READ_PARAMETER_PAGE: 464 1.1 ahoka if (address == 0x00) { 465 1.1 ahoka sc->sc_io_len = sizeof(struct onfi_parameter_page) * 4; 466 1.1 ahoka sc->sc_io_pointer = (uint8_t *)sc->sc_parameter_page; 467 1.1 ahoka } else { 468 1.1 ahoka sc->sc_io_len = 0; 469 1.1 ahoka } 470 1.1 ahoka break; 471 1.1 ahoka case ONFI_PAGE_PROGRAM: 472 1.1 ahoka sc->sc_address <<= 8; 473 1.1 ahoka sc->sc_address |= address; 474 1.1 ahoka sc->sc_address_counter++; 475 1.5 ahoka 476 1.1 ahoka if (sc->sc_address_counter == 477 1.1 ahoka sc->sc_column_cycles + sc->sc_row_cycles) { 478 1.1 ahoka nandemulator_address_chip(self); 479 1.1 ahoka } 480 1.1 ahoka break; 481 1.1 ahoka default: 482 1.1 ahoka sc->sc_address <<= 8; 483 1.1 ahoka sc->sc_address |= address; 484 1.1 ahoka sc->sc_address_counter++; 485 1.1 ahoka } 486 1.1 ahoka }; 487 1.1 ahoka 488 1.1 ahoka static void 489 1.1 ahoka nandemulator_busy(device_t self) 490 1.1 ahoka { 491 1.1 ahoka #ifdef NANDEMULATOR_DELAYS 492 1.1 ahoka struct nandemulator_softc *sc = device_private(self); 493 1.1 ahoka 494 1.1 ahoka /* do some delay depending on command */ 495 1.1 ahoka switch (sc->sc_command) { 496 1.1 ahoka case ONFI_PAGE_PROGRAM_START: 497 1.1 ahoka case ONFI_BLOCK_ERASE_START: 498 1.1 ahoka DELAY(10); 499 1.1 ahoka break; 500 1.1 ahoka case ONFI_READ_START: 501 1.1 ahoka default: 502 1.1 ahoka DELAY(1); 503 1.1 ahoka } 504 1.1 ahoka #endif 505 1.1 ahoka } 506 1.1 ahoka 507 1.1 ahoka static void 508 1.5 ahoka nandemulator_read_1(device_t self, uint8_t *data) 509 1.1 ahoka { 510 1.1 ahoka struct nandemulator_softc *sc = device_private(self); 511 1.1 ahoka 512 1.3 ahoka KASSERT(sc->sc_io_len > 0); 513 1.3 ahoka 514 1.1 ahoka if (sc->sc_io_len > 0) { 515 1.1 ahoka *data = *sc->sc_io_pointer; 516 1.1 ahoka 517 1.1 ahoka sc->sc_io_pointer++; 518 1.1 ahoka sc->sc_io_len--; 519 1.1 ahoka } else { 520 1.1 ahoka aprint_error_dev(self, "reading byte from invalid location\n"); 521 1.1 ahoka *data = 0xff; 522 1.1 ahoka } 523 1.1 ahoka } 524 1.1 ahoka 525 1.1 ahoka static void 526 1.5 ahoka nandemulator_write_1(device_t self, uint8_t data) 527 1.1 ahoka { 528 1.1 ahoka struct nandemulator_softc *sc = device_private(self); 529 1.1 ahoka 530 1.3 ahoka KASSERT(sc->sc_register_writable); 531 1.3 ahoka 532 1.1 ahoka if (!sc->sc_register_writable) { 533 1.1 ahoka aprint_error_dev(self, 534 1.1 ahoka "trying to write read only location without effect\n"); 535 1.1 ahoka return; 536 1.1 ahoka } 537 1.1 ahoka 538 1.3 ahoka KASSERT(sc->sc_io_len > 0); 539 1.3 ahoka 540 1.1 ahoka if (sc->sc_io_len > 0) { 541 1.1 ahoka *sc->sc_io_pointer = data; 542 1.1 ahoka 543 1.1 ahoka sc->sc_io_pointer++; 544 1.1 ahoka sc->sc_io_len--; 545 1.1 ahoka } else { 546 1.1 ahoka aprint_error_dev(self, "write to invalid location\n"); 547 1.1 ahoka } 548 1.1 ahoka } 549 1.1 ahoka 550 1.1 ahoka static void 551 1.5 ahoka nandemulator_read_2(device_t self, uint16_t *data) 552 1.1 ahoka { 553 1.1 ahoka struct nandemulator_softc *sc = device_private(self); 554 1.1 ahoka 555 1.3 ahoka KASSERT(sc->sc_buswidth == NANDEMULATOR_16BIT); 556 1.3 ahoka 557 1.1 ahoka if (sc->sc_buswidth != NANDEMULATOR_16BIT) { 558 1.1 ahoka aprint_error_dev(self, 559 1.1 ahoka "trying to read a word on an 8bit chip\n"); 560 1.1 ahoka return; 561 1.1 ahoka } 562 1.1 ahoka 563 1.3 ahoka KASSERT(sc->sc_io_len > 1); 564 1.3 ahoka 565 1.1 ahoka if (sc->sc_io_len > 1) { 566 1.1 ahoka *data = *(uint16_t *)sc->sc_io_pointer; 567 1.1 ahoka 568 1.1 ahoka sc->sc_io_pointer += 2; 569 1.1 ahoka sc->sc_io_len -= 2; 570 1.1 ahoka } else { 571 1.1 ahoka aprint_error_dev(self, "reading word from invalid location\n"); 572 1.1 ahoka *data = 0xffff; 573 1.1 ahoka } 574 1.1 ahoka } 575 1.1 ahoka 576 1.1 ahoka static void 577 1.5 ahoka nandemulator_write_2(device_t self, uint16_t data) 578 1.1 ahoka { 579 1.1 ahoka struct nandemulator_softc *sc = device_private(self); 580 1.1 ahoka 581 1.3 ahoka KASSERT(sc->sc_register_writable); 582 1.3 ahoka 583 1.1 ahoka if (!sc->sc_register_writable) { 584 1.1 ahoka aprint_error_dev(self, 585 1.1 ahoka "trying to write read only location without effect\n"); 586 1.1 ahoka return; 587 1.1 ahoka } 588 1.1 ahoka 589 1.3 ahoka KASSERT(sc->sc_buswidth == NANDEMULATOR_16BIT); 590 1.3 ahoka 591 1.1 ahoka if (sc->sc_buswidth != NANDEMULATOR_16BIT) { 592 1.1 ahoka aprint_error_dev(self, 593 1.1 ahoka "trying to write a word to an 8bit chip"); 594 1.1 ahoka return; 595 1.1 ahoka } 596 1.1 ahoka 597 1.3 ahoka KASSERT(sc->sc_io_len > 1); 598 1.3 ahoka 599 1.1 ahoka if (sc->sc_io_len > 1) { 600 1.1 ahoka *(uint16_t *)sc->sc_io_pointer = data; 601 1.1 ahoka 602 1.1 ahoka sc->sc_io_pointer += 2; 603 1.1 ahoka sc->sc_io_len -= 2; 604 1.1 ahoka } else { 605 1.1 ahoka aprint_error_dev(self, "writing to invalid location"); 606 1.1 ahoka } 607 1.1 ahoka } 608 1.1 ahoka 609 1.1 ahoka static void 610 1.5 ahoka nandemulator_read_buf_1(device_t self, void *buf, size_t len) 611 1.1 ahoka { 612 1.1 ahoka uint8_t *addr; 613 1.1 ahoka 614 1.1 ahoka KASSERT(buf != NULL); 615 1.1 ahoka KASSERT(len >= 1); 616 1.1 ahoka 617 1.1 ahoka addr = buf; 618 1.1 ahoka while (len > 0) { 619 1.5 ahoka nandemulator_read_1(self, addr); 620 1.1 ahoka addr++, len--; 621 1.1 ahoka } 622 1.1 ahoka } 623 1.1 ahoka 624 1.1 ahoka static void 625 1.5 ahoka nandemulator_read_buf_2(device_t self, void *buf, size_t len) 626 1.1 ahoka { 627 1.1 ahoka uint16_t *addr; 628 1.1 ahoka 629 1.1 ahoka KASSERT(buf != NULL); 630 1.1 ahoka KASSERT(len >= 2); 631 1.1 ahoka KASSERT(!(len & 0x01)); 632 1.1 ahoka 633 1.1 ahoka addr = buf; 634 1.1 ahoka len /= 2; 635 1.1 ahoka while (len > 0) { 636 1.5 ahoka nandemulator_read_2(self, addr); 637 1.1 ahoka addr++, len--; 638 1.1 ahoka } 639 1.1 ahoka } 640 1.1 ahoka 641 1.1 ahoka static void 642 1.5 ahoka nandemulator_write_buf_1(device_t self, const void *buf, size_t len) 643 1.1 ahoka { 644 1.1 ahoka const uint8_t *addr; 645 1.1 ahoka 646 1.1 ahoka KASSERT(buf != NULL); 647 1.1 ahoka KASSERT(len >= 1); 648 1.1 ahoka 649 1.1 ahoka addr = buf; 650 1.1 ahoka while (len > 0) { 651 1.5 ahoka nandemulator_write_1(self, *addr); 652 1.1 ahoka addr++, len--; 653 1.1 ahoka } 654 1.1 ahoka } 655 1.1 ahoka 656 1.1 ahoka static void 657 1.5 ahoka nandemulator_write_buf_2(device_t self, const void *buf, size_t len) 658 1.1 ahoka { 659 1.1 ahoka const uint16_t *addr; 660 1.1 ahoka 661 1.1 ahoka KASSERT(buf != NULL); 662 1.1 ahoka KASSERT(len >= 2); 663 1.1 ahoka KASSERT(!(len & 0x01)); 664 1.1 ahoka 665 1.1 ahoka addr = buf; 666 1.1 ahoka len /= 2; 667 1.1 ahoka while (len > 0) { 668 1.5 ahoka nandemulator_write_2(self, *addr); 669 1.1 ahoka addr++, len--; 670 1.1 ahoka } 671 1.1 ahoka } 672 1.1 ahoka 673 1.1 ahoka static size_t 674 1.1 ahoka nandemulator_address_to_page(device_t self) 675 1.1 ahoka { 676 1.1 ahoka struct nandemulator_softc *sc = device_private(self); 677 1.1 ahoka uint64_t address, offset; 678 1.1 ahoka int i; 679 1.1 ahoka 680 1.1 ahoka address = htole64(sc->sc_address); 681 1.1 ahoka address &= sc->sc_row_mask; 682 1.1 ahoka 683 1.1 ahoka offset = 0; 684 1.1 ahoka for (i = 0; i < sc->sc_row_cycles; i++) { 685 1.1 ahoka offset <<= 8; 686 1.1 ahoka offset |= (address & 0xff); 687 1.1 ahoka address >>= 8; 688 1.1 ahoka } 689 1.1 ahoka 690 1.1 ahoka return le64toh(offset); 691 1.1 ahoka } 692 1.1 ahoka 693 1.1 ahoka static size_t 694 1.1 ahoka nandemulator_column_address_to_subpage(device_t self) 695 1.1 ahoka { 696 1.1 ahoka struct nandemulator_softc *sc = device_private(self); 697 1.1 ahoka uint64_t address, offset; 698 1.1 ahoka int i; 699 1.1 ahoka 700 1.1 ahoka address = htole64(sc->sc_address); 701 1.1 ahoka address >>= (8 * sc->sc_row_cycles); 702 1.1 ahoka 703 1.1 ahoka offset = 0; 704 1.1 ahoka for (i = 0; i < sc->sc_column_cycles; i++) { 705 1.1 ahoka offset <<= 8; 706 1.1 ahoka offset |= (address & 0xff); 707 1.1 ahoka address >>= 8; 708 1.1 ahoka } 709 1.1 ahoka 710 1.1 ahoka if (sc->sc_buswidth == NANDEMULATOR_16BIT) 711 1.1 ahoka return (size_t )le64toh(offset << 1); 712 1.1 ahoka else 713 1.1 ahoka return (size_t )le64toh(offset); 714 1.1 ahoka } 715 1.1 ahoka 716 1.1 ahoka static size_t 717 1.1 ahoka nandemulator_page_to_backend_offset(device_t self, size_t page) 718 1.1 ahoka { 719 1.1 ahoka struct nandemulator_softc *sc = device_private(self); 720 1.1 ahoka 721 1.1 ahoka return (sc->sc_page_size + sc->sc_spare_size) * page; 722 1.1 ahoka } 723 1.1 ahoka 724 1.1 ahoka #ifdef _MODULE 725 1.1 ahoka 726 1.1 ahoka MODULE(MODULE_CLASS_DRIVER, nandemulator, "nand"); 727 1.1 ahoka 728 1.1 ahoka static const struct cfiattrdata nandbuscf_iattrdata = { 729 1.1 ahoka "nandbus", 0, { { NULL, NULL, 0 }, } 730 1.1 ahoka }; 731 1.1 ahoka static const struct cfiattrdata * const nandemulator_attrs[] = { 732 1.1 ahoka &nandbuscf_iattrdata, NULL 733 1.1 ahoka }; 734 1.1 ahoka 735 1.1 ahoka CFDRIVER_DECL(nandemulator, DV_DULL, nandemulator_attrs); 736 1.1 ahoka extern struct cfattach nandemulator_ca; 737 1.1 ahoka static int nandemulatorloc[] = { -1, -1 }; 738 1.1 ahoka 739 1.1 ahoka static struct cfdata nandemulator_cfdata[] = { 740 1.1 ahoka { 741 1.1 ahoka .cf_name = "nandemulator", 742 1.1 ahoka .cf_atname = "nandemulator", 743 1.1 ahoka .cf_unit = 0, 744 1.1 ahoka .cf_fstate = FSTATE_STAR, 745 1.1 ahoka .cf_loc = nandemulatorloc, 746 1.1 ahoka .cf_flags = 0, 747 1.1 ahoka .cf_pspec = NULL, 748 1.1 ahoka }, 749 1.1 ahoka { NULL, NULL, 0, 0, NULL, 0, NULL } 750 1.1 ahoka }; 751 1.1 ahoka 752 1.1 ahoka static int 753 1.1 ahoka nandemulator_modcmd(modcmd_t cmd, void *arg) 754 1.1 ahoka { 755 1.1 ahoka int error; 756 1.1 ahoka 757 1.1 ahoka switch (cmd) { 758 1.1 ahoka case MODULE_CMD_INIT: 759 1.1 ahoka error = config_cfdriver_attach(&nandemulator_cd); 760 1.1 ahoka if (error) { 761 1.1 ahoka return error; 762 1.1 ahoka } 763 1.1 ahoka 764 1.1 ahoka error = config_cfattach_attach(nandemulator_cd.cd_name, 765 1.1 ahoka &nandemulator_ca); 766 1.1 ahoka if (error) { 767 1.1 ahoka config_cfdriver_detach(&nandemulator_cd); 768 1.1 ahoka aprint_error("%s: unable to register cfattach\n", 769 1.1 ahoka nandemulator_cd.cd_name); 770 1.1 ahoka 771 1.1 ahoka return error; 772 1.1 ahoka } 773 1.1 ahoka 774 1.1 ahoka error = config_cfdata_attach(nandemulator_cfdata, 1); 775 1.1 ahoka if (error) { 776 1.1 ahoka config_cfattach_detach(nandemulator_cd.cd_name, 777 1.1 ahoka &nandemulator_ca); 778 1.1 ahoka config_cfdriver_detach(&nandemulator_cd); 779 1.1 ahoka aprint_error("%s: unable to register cfdata\n", 780 1.1 ahoka nandemulator_cd.cd_name); 781 1.1 ahoka 782 1.1 ahoka return error; 783 1.1 ahoka } 784 1.1 ahoka 785 1.1 ahoka (void)config_attach_pseudo(nandemulator_cfdata); 786 1.1 ahoka 787 1.1 ahoka return 0; 788 1.4 ahoka 789 1.1 ahoka case MODULE_CMD_FINI: 790 1.1 ahoka error = config_cfdata_detach(nandemulator_cfdata); 791 1.1 ahoka if (error) { 792 1.1 ahoka return error; 793 1.1 ahoka } 794 1.1 ahoka 795 1.1 ahoka config_cfattach_detach(nandemulator_cd.cd_name, 796 1.1 ahoka &nandemulator_ca); 797 1.1 ahoka config_cfdriver_detach(&nandemulator_cd); 798 1.1 ahoka 799 1.1 ahoka return 0; 800 1.4 ahoka 801 1.4 ahoka case MODULE_CMD_AUTOUNLOAD: 802 1.4 ahoka /* prevent auto-unload */ 803 1.4 ahoka return EBUSY; 804 1.4 ahoka 805 1.1 ahoka default: 806 1.1 ahoka return ENOTTY; 807 1.1 ahoka } 808 1.1 ahoka } 809 1.1 ahoka 810 1.1 ahoka #endif 811