1 /* 2 * ST M25P80 emulator. Emulate all SPI flash devices based on the m25p80 command 3 * set. Known devices table current as of Jun/2012 and taken from linux. 4 * See drivers/mtd/devices/m25p80.c. 5 * 6 * Copyright (C) 2011 Edgar E. Iglesias <edgar.iglesias@gmail.com> 7 * Copyright (C) 2012 Peter A. G. Crosthwaite <peter.crosthwaite@petalogix.com> 8 * Copyright (C) 2012 PetaLogix 9 * 10 * This program is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU General Public License as 12 * published by the Free Software Foundation; either version 2 or 13 * (at your option) a later version of the License. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License along 21 * with this program; if not, see <http://www.gnu.org/licenses/>. 22 */ 23 24 #include "qemu/osdep.h" 25 #include "hw/hw.h" 26 #include "sysemu/block-backend.h" 27 #include "sysemu/blockdev.h" 28 #include "hw/ssi/ssi.h" 29 #include "qemu/bitops.h" 30 #include "qemu/log.h" 31 #include "qapi/error.h" 32 33 #ifndef M25P80_ERR_DEBUG 34 #define M25P80_ERR_DEBUG 0 35 #endif 36 37 #define DB_PRINT_L(level, ...) do { \ 38 if (M25P80_ERR_DEBUG > (level)) { \ 39 fprintf(stderr, ": %s: ", __func__); \ 40 fprintf(stderr, ## __VA_ARGS__); \ 41 } \ 42 } while (0); 43 44 /* Fields for FlashPartInfo->flags */ 45 46 /* erase capabilities */ 47 #define ER_4K 1 48 #define ER_32K 2 49 /* set to allow the page program command to write 0s back to 1. Useful for 50 * modelling EEPROM with SPI flash command set 51 */ 52 #define EEPROM 0x100 53 54 /* 16 MiB max in 3 byte address mode */ 55 #define MAX_3BYTES_SIZE 0x1000000 56 57 #define SPI_NOR_MAX_ID_LEN 6 58 59 typedef struct FlashPartInfo { 60 const char *part_name; 61 /* 62 * This array stores the ID bytes. 63 * The first three bytes are the JEDIC ID. 64 * JEDEC ID zero means "no ID" (mostly older chips). 65 */ 66 uint8_t id[SPI_NOR_MAX_ID_LEN]; 67 uint8_t id_len; 68 /* there is confusion between manufacturers as to what a sector is. In this 69 * device model, a "sector" is the size that is erased by the ERASE_SECTOR 70 * command (opcode 0xd8). 71 */ 72 uint32_t sector_size; 73 uint32_t n_sectors; 74 uint32_t page_size; 75 uint16_t flags; 76 } FlashPartInfo; 77 78 /* adapted from linux */ 79 /* Used when the "_ext_id" is two bytes at most */ 80 #define INFO(_part_name, _jedec_id, _ext_id, _sector_size, _n_sectors, _flags)\ 81 .part_name = _part_name,\ 82 .id = {\ 83 ((_jedec_id) >> 16) & 0xff,\ 84 ((_jedec_id) >> 8) & 0xff,\ 85 (_jedec_id) & 0xff,\ 86 ((_ext_id) >> 8) & 0xff,\ 87 (_ext_id) & 0xff,\ 88 },\ 89 .id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))),\ 90 .sector_size = (_sector_size),\ 91 .n_sectors = (_n_sectors),\ 92 .page_size = 256,\ 93 .flags = (_flags), 94 95 #define INFO6(_part_name, _jedec_id, _ext_id, _sector_size, _n_sectors, _flags)\ 96 .part_name = _part_name,\ 97 .id = {\ 98 ((_jedec_id) >> 16) & 0xff,\ 99 ((_jedec_id) >> 8) & 0xff,\ 100 (_jedec_id) & 0xff,\ 101 ((_ext_id) >> 16) & 0xff,\ 102 ((_ext_id) >> 8) & 0xff,\ 103 (_ext_id) & 0xff,\ 104 },\ 105 .id_len = 6,\ 106 .sector_size = (_sector_size),\ 107 .n_sectors = (_n_sectors),\ 108 .page_size = 256,\ 109 .flags = (_flags),\ 110 111 #define JEDEC_NUMONYX 0x20 112 #define JEDEC_WINBOND 0xEF 113 #define JEDEC_SPANSION 0x01 114 115 /* Numonyx (Micron) Configuration register macros */ 116 #define VCFG_DUMMY 0x1 117 #define VCFG_WRAP_SEQUENTIAL 0x2 118 #define NVCFG_XIP_MODE_DISABLED (7 << 9) 119 #define NVCFG_XIP_MODE_MASK (7 << 9) 120 #define VCFG_XIP_MODE_ENABLED (1 << 3) 121 #define CFG_DUMMY_CLK_LEN 4 122 #define NVCFG_DUMMY_CLK_POS 12 123 #define VCFG_DUMMY_CLK_POS 4 124 #define EVCFG_OUT_DRIVER_STRENGHT_DEF 7 125 #define EVCFG_VPP_ACCELERATOR (1 << 3) 126 #define EVCFG_RESET_HOLD_ENABLED (1 << 4) 127 #define NVCFG_DUAL_IO_MASK (1 << 2) 128 #define EVCFG_DUAL_IO_ENABLED (1 << 6) 129 #define NVCFG_QUAD_IO_MASK (1 << 3) 130 #define EVCFG_QUAD_IO_ENABLED (1 << 7) 131 #define NVCFG_4BYTE_ADDR_MASK (1 << 0) 132 #define NVCFG_LOWER_SEGMENT_MASK (1 << 1) 133 134 /* Numonyx (Micron) Flag Status Register macros */ 135 #define FSR_4BYTE_ADDR_MODE_ENABLED 0x1 136 #define FSR_FLASH_READY (1 << 7) 137 138 /* Spansion configuration registers macros. */ 139 #define SPANSION_QUAD_CFG_POS 0 140 #define SPANSION_QUAD_CFG_LEN 1 141 #define SPANSION_DUMMY_CLK_POS 0 142 #define SPANSION_DUMMY_CLK_LEN 4 143 #define SPANSION_ADDR_LEN_POS 7 144 #define SPANSION_ADDR_LEN_LEN 1 145 146 /* 147 * Spansion read mode command length in bytes, 148 * the mode is currently not supported. 149 */ 150 151 #define SPANSION_CONTINUOUS_READ_MODE_CMD_LEN 1 152 #define WINBOND_CONTINUOUS_READ_MODE_CMD_LEN 1 153 154 static const FlashPartInfo known_devices[] = { 155 /* Atmel -- some are (confusingly) marketed as "DataFlash" */ 156 { INFO("at25fs010", 0x1f6601, 0, 32 << 10, 4, ER_4K) }, 157 { INFO("at25fs040", 0x1f6604, 0, 64 << 10, 8, ER_4K) }, 158 159 { INFO("at25df041a", 0x1f4401, 0, 64 << 10, 8, ER_4K) }, 160 { INFO("at25df321a", 0x1f4701, 0, 64 << 10, 64, ER_4K) }, 161 { INFO("at25df641", 0x1f4800, 0, 64 << 10, 128, ER_4K) }, 162 163 { INFO("at26f004", 0x1f0400, 0, 64 << 10, 8, ER_4K) }, 164 { INFO("at26df081a", 0x1f4501, 0, 64 << 10, 16, ER_4K) }, 165 { INFO("at26df161a", 0x1f4601, 0, 64 << 10, 32, ER_4K) }, 166 { INFO("at26df321", 0x1f4700, 0, 64 << 10, 64, ER_4K) }, 167 168 { INFO("at45db081d", 0x1f2500, 0, 64 << 10, 16, ER_4K) }, 169 170 /* Atmel EEPROMS - it is assumed, that don't care bit in command 171 * is set to 0. Block protection is not supported. 172 */ 173 { INFO("at25128a-nonjedec", 0x0, 0, 1, 131072, EEPROM) }, 174 { INFO("at25256a-nonjedec", 0x0, 0, 1, 262144, EEPROM) }, 175 176 /* EON -- en25xxx */ 177 { INFO("en25f32", 0x1c3116, 0, 64 << 10, 64, ER_4K) }, 178 { INFO("en25p32", 0x1c2016, 0, 64 << 10, 64, 0) }, 179 { INFO("en25q32b", 0x1c3016, 0, 64 << 10, 64, 0) }, 180 { INFO("en25p64", 0x1c2017, 0, 64 << 10, 128, 0) }, 181 { INFO("en25q64", 0x1c3017, 0, 64 << 10, 128, ER_4K) }, 182 183 /* GigaDevice */ 184 { INFO("gd25q32", 0xc84016, 0, 64 << 10, 64, ER_4K) }, 185 { INFO("gd25q64", 0xc84017, 0, 64 << 10, 128, ER_4K) }, 186 187 /* Intel/Numonyx -- xxxs33b */ 188 { INFO("160s33b", 0x898911, 0, 64 << 10, 32, 0) }, 189 { INFO("320s33b", 0x898912, 0, 64 << 10, 64, 0) }, 190 { INFO("640s33b", 0x898913, 0, 64 << 10, 128, 0) }, 191 { INFO("n25q064", 0x20ba17, 0, 64 << 10, 128, 0) }, 192 193 /* Macronix */ 194 { INFO("mx25l2005a", 0xc22012, 0, 64 << 10, 4, ER_4K) }, 195 { INFO("mx25l4005a", 0xc22013, 0, 64 << 10, 8, ER_4K) }, 196 { INFO("mx25l8005", 0xc22014, 0, 64 << 10, 16, 0) }, 197 { INFO("mx25l1606e", 0xc22015, 0, 64 << 10, 32, ER_4K) }, 198 { INFO("mx25l3205d", 0xc22016, 0, 64 << 10, 64, 0) }, 199 { INFO("mx25l6405d", 0xc22017, 0, 64 << 10, 128, 0) }, 200 { INFO("mx25l12805d", 0xc22018, 0, 64 << 10, 256, 0) }, 201 { INFO("mx25l12855e", 0xc22618, 0, 64 << 10, 256, 0) }, 202 { INFO("mx25l25635e", 0xc22019, 0, 64 << 10, 512, 0) }, 203 { INFO("mx25l25655e", 0xc22619, 0, 64 << 10, 512, 0) }, 204 { INFO("mx66u51235f", 0xc2253a, 0, 64 << 10, 1024, ER_4K | ER_32K) }, 205 { INFO("mx66u1g45g", 0xc2253b, 0, 64 << 10, 2048, ER_4K | ER_32K) }, 206 207 /* Micron */ 208 { INFO("n25q032a11", 0x20bb16, 0, 64 << 10, 64, ER_4K) }, 209 { INFO("n25q032a13", 0x20ba16, 0, 64 << 10, 64, ER_4K) }, 210 { INFO("n25q064a11", 0x20bb17, 0, 64 << 10, 128, ER_4K) }, 211 { INFO("n25q064a13", 0x20ba17, 0, 64 << 10, 128, ER_4K) }, 212 { INFO("n25q128a11", 0x20bb18, 0, 64 << 10, 256, ER_4K) }, 213 { INFO("n25q128a13", 0x20ba18, 0, 64 << 10, 256, ER_4K) }, 214 { INFO("n25q256a11", 0x20bb19, 0, 64 << 10, 512, ER_4K) }, 215 { INFO("n25q256a13", 0x20ba19, 0, 64 << 10, 512, ER_4K) }, 216 { INFO("n25q128", 0x20ba18, 0, 64 << 10, 256, 0) }, 217 { INFO("n25q256a", 0x20ba19, 0, 64 << 10, 512, ER_4K) }, 218 { INFO("n25q512a", 0x20ba20, 0, 64 << 10, 1024, ER_4K) }, 219 { INFO("mt25ql01g", 0x20ba21, 0, 64 << 10, 2048, ER_4K) }, 220 { INFO("mt25qu01g", 0x20bb21, 0, 64 << 10, 2048, ER_4K) }, 221 222 /* Spansion -- single (large) sector size only, at least 223 * for the chips listed here (without boot sectors). 224 */ 225 { INFO("s25sl032p", 0x010215, 0x4d00, 64 << 10, 64, ER_4K) }, 226 { INFO("s25sl064p", 0x010216, 0x4d00, 64 << 10, 128, ER_4K) }, 227 { INFO("s25fl256s0", 0x010219, 0x4d00, 256 << 10, 128, 0) }, 228 { INFO("s25fl256s1", 0x010219, 0x4d01, 64 << 10, 512, 0) }, 229 { INFO6("s25fl512s", 0x010220, 0x4d0080, 256 << 10, 256, 0) }, 230 { INFO6("s70fl01gs", 0x010221, 0x4d0080, 256 << 10, 512, 0) }, 231 { INFO("s25sl12800", 0x012018, 0x0300, 256 << 10, 64, 0) }, 232 { INFO("s25sl12801", 0x012018, 0x0301, 64 << 10, 256, 0) }, 233 { INFO("s25fl129p0", 0x012018, 0x4d00, 256 << 10, 64, 0) }, 234 { INFO("s25fl129p1", 0x012018, 0x4d01, 64 << 10, 256, 0) }, 235 { INFO("s25sl004a", 0x010212, 0, 64 << 10, 8, 0) }, 236 { INFO("s25sl008a", 0x010213, 0, 64 << 10, 16, 0) }, 237 { INFO("s25sl016a", 0x010214, 0, 64 << 10, 32, 0) }, 238 { INFO("s25sl032a", 0x010215, 0, 64 << 10, 64, 0) }, 239 { INFO("s25sl064a", 0x010216, 0, 64 << 10, 128, 0) }, 240 { INFO("s25fl016k", 0xef4015, 0, 64 << 10, 32, ER_4K | ER_32K) }, 241 { INFO("s25fl064k", 0xef4017, 0, 64 << 10, 128, ER_4K | ER_32K) }, 242 243 /* Spansion -- boot sectors support */ 244 { INFO6("s25fs512s", 0x010220, 0x4d0081, 256 << 10, 256, 0) }, 245 { INFO6("s70fs01gs", 0x010221, 0x4d0081, 256 << 10, 512, 0) }, 246 247 /* SST -- large erase sizes are "overlays", "sectors" are 4<< 10 */ 248 { INFO("sst25vf040b", 0xbf258d, 0, 64 << 10, 8, ER_4K) }, 249 { INFO("sst25vf080b", 0xbf258e, 0, 64 << 10, 16, ER_4K) }, 250 { INFO("sst25vf016b", 0xbf2541, 0, 64 << 10, 32, ER_4K) }, 251 { INFO("sst25vf032b", 0xbf254a, 0, 64 << 10, 64, ER_4K) }, 252 { INFO("sst25wf512", 0xbf2501, 0, 64 << 10, 1, ER_4K) }, 253 { INFO("sst25wf010", 0xbf2502, 0, 64 << 10, 2, ER_4K) }, 254 { INFO("sst25wf020", 0xbf2503, 0, 64 << 10, 4, ER_4K) }, 255 { INFO("sst25wf040", 0xbf2504, 0, 64 << 10, 8, ER_4K) }, 256 { INFO("sst25wf080", 0xbf2505, 0, 64 << 10, 16, ER_4K) }, 257 258 /* ST Microelectronics -- newer production may have feature updates */ 259 { INFO("m25p05", 0x202010, 0, 32 << 10, 2, 0) }, 260 { INFO("m25p10", 0x202011, 0, 32 << 10, 4, 0) }, 261 { INFO("m25p20", 0x202012, 0, 64 << 10, 4, 0) }, 262 { INFO("m25p40", 0x202013, 0, 64 << 10, 8, 0) }, 263 { INFO("m25p80", 0x202014, 0, 64 << 10, 16, 0) }, 264 { INFO("m25p16", 0x202015, 0, 64 << 10, 32, 0) }, 265 { INFO("m25p32", 0x202016, 0, 64 << 10, 64, 0) }, 266 { INFO("m25p64", 0x202017, 0, 64 << 10, 128, 0) }, 267 { INFO("m25p128", 0x202018, 0, 256 << 10, 64, 0) }, 268 { INFO("n25q032", 0x20ba16, 0, 64 << 10, 64, 0) }, 269 270 { INFO("m45pe10", 0x204011, 0, 64 << 10, 2, 0) }, 271 { INFO("m45pe80", 0x204014, 0, 64 << 10, 16, 0) }, 272 { INFO("m45pe16", 0x204015, 0, 64 << 10, 32, 0) }, 273 274 { INFO("m25pe20", 0x208012, 0, 64 << 10, 4, 0) }, 275 { INFO("m25pe80", 0x208014, 0, 64 << 10, 16, 0) }, 276 { INFO("m25pe16", 0x208015, 0, 64 << 10, 32, ER_4K) }, 277 278 { INFO("m25px32", 0x207116, 0, 64 << 10, 64, ER_4K) }, 279 { INFO("m25px32-s0", 0x207316, 0, 64 << 10, 64, ER_4K) }, 280 { INFO("m25px32-s1", 0x206316, 0, 64 << 10, 64, ER_4K) }, 281 { INFO("m25px64", 0x207117, 0, 64 << 10, 128, 0) }, 282 283 /* Winbond -- w25x "blocks" are 64k, "sectors" are 4KiB */ 284 { INFO("w25x10", 0xef3011, 0, 64 << 10, 2, ER_4K) }, 285 { INFO("w25x20", 0xef3012, 0, 64 << 10, 4, ER_4K) }, 286 { INFO("w25x40", 0xef3013, 0, 64 << 10, 8, ER_4K) }, 287 { INFO("w25x80", 0xef3014, 0, 64 << 10, 16, ER_4K) }, 288 { INFO("w25x16", 0xef3015, 0, 64 << 10, 32, ER_4K) }, 289 { INFO("w25x32", 0xef3016, 0, 64 << 10, 64, ER_4K) }, 290 { INFO("w25q32", 0xef4016, 0, 64 << 10, 64, ER_4K) }, 291 { INFO("w25q32dw", 0xef6016, 0, 64 << 10, 64, ER_4K) }, 292 { INFO("w25x64", 0xef3017, 0, 64 << 10, 128, ER_4K) }, 293 { INFO("w25q64", 0xef4017, 0, 64 << 10, 128, ER_4K) }, 294 { INFO("w25q80", 0xef5014, 0, 64 << 10, 16, ER_4K) }, 295 { INFO("w25q80bl", 0xef4014, 0, 64 << 10, 16, ER_4K) }, 296 { INFO("w25q256", 0xef4019, 0, 64 << 10, 512, ER_4K) }, 297 }; 298 299 typedef enum { 300 NOP = 0, 301 WRSR = 0x1, 302 WRDI = 0x4, 303 RDSR = 0x5, 304 WREN = 0x6, 305 JEDEC_READ = 0x9f, 306 BULK_ERASE = 0xc7, 307 READ_FSR = 0x70, 308 RDCR = 0x15, 309 310 READ = 0x03, 311 READ4 = 0x13, 312 FAST_READ = 0x0b, 313 FAST_READ4 = 0x0c, 314 DOR = 0x3b, 315 DOR4 = 0x3c, 316 QOR = 0x6b, 317 QOR4 = 0x6c, 318 DIOR = 0xbb, 319 DIOR4 = 0xbc, 320 QIOR = 0xeb, 321 QIOR4 = 0xec, 322 323 PP = 0x02, 324 PP4 = 0x12, 325 PP4_4 = 0x3e, 326 DPP = 0xa2, 327 QPP = 0x32, 328 329 ERASE_4K = 0x20, 330 ERASE4_4K = 0x21, 331 ERASE_32K = 0x52, 332 ERASE4_32K = 0x5c, 333 ERASE_SECTOR = 0xd8, 334 ERASE4_SECTOR = 0xdc, 335 336 EN_4BYTE_ADDR = 0xB7, 337 EX_4BYTE_ADDR = 0xE9, 338 339 EXTEND_ADDR_READ = 0xC8, 340 EXTEND_ADDR_WRITE = 0xC5, 341 342 RESET_ENABLE = 0x66, 343 RESET_MEMORY = 0x99, 344 345 /* 346 * Micron: 0x35 - enable QPI 347 * Spansion: 0x35 - read control register 348 */ 349 RDCR_EQIO = 0x35, 350 RSTQIO = 0xf5, 351 352 RNVCR = 0xB5, 353 WNVCR = 0xB1, 354 355 RVCR = 0x85, 356 WVCR = 0x81, 357 358 REVCR = 0x65, 359 WEVCR = 0x61, 360 } FlashCMD; 361 362 typedef enum { 363 STATE_IDLE, 364 STATE_PAGE_PROGRAM, 365 STATE_READ, 366 STATE_COLLECTING_DATA, 367 STATE_COLLECTING_VAR_LEN_DATA, 368 STATE_READING_DATA, 369 } CMDState; 370 371 typedef enum { 372 MAN_SPANSION, 373 MAN_MACRONIX, 374 MAN_NUMONYX, 375 MAN_WINBOND, 376 MAN_GENERIC, 377 } Manufacturer; 378 379 typedef struct Flash { 380 SSISlave parent_obj; 381 382 BlockBackend *blk; 383 384 uint8_t *storage; 385 uint32_t size; 386 int page_size; 387 388 uint8_t state; 389 uint8_t data[16]; 390 uint32_t len; 391 uint32_t pos; 392 uint8_t needed_bytes; 393 uint8_t cmd_in_progress; 394 uint32_t cur_addr; 395 uint32_t nonvolatile_cfg; 396 /* Configuration register for Macronix */ 397 uint32_t volatile_cfg; 398 uint32_t enh_volatile_cfg; 399 /* Spansion cfg registers. */ 400 uint8_t spansion_cr1nv; 401 uint8_t spansion_cr2nv; 402 uint8_t spansion_cr3nv; 403 uint8_t spansion_cr4nv; 404 uint8_t spansion_cr1v; 405 uint8_t spansion_cr2v; 406 uint8_t spansion_cr3v; 407 uint8_t spansion_cr4v; 408 bool write_enable; 409 bool four_bytes_address_mode; 410 bool reset_enable; 411 bool quad_enable; 412 uint8_t ear; 413 414 int64_t dirty_page; 415 416 const FlashPartInfo *pi; 417 418 } Flash; 419 420 typedef struct M25P80Class { 421 SSISlaveClass parent_class; 422 FlashPartInfo *pi; 423 } M25P80Class; 424 425 #define TYPE_M25P80 "m25p80-generic" 426 #define M25P80(obj) \ 427 OBJECT_CHECK(Flash, (obj), TYPE_M25P80) 428 #define M25P80_CLASS(klass) \ 429 OBJECT_CLASS_CHECK(M25P80Class, (klass), TYPE_M25P80) 430 #define M25P80_GET_CLASS(obj) \ 431 OBJECT_GET_CLASS(M25P80Class, (obj), TYPE_M25P80) 432 433 static inline Manufacturer get_man(Flash *s) 434 { 435 switch (s->pi->id[0]) { 436 case 0x20: 437 return MAN_NUMONYX; 438 case 0xEF: 439 return MAN_WINBOND; 440 case 0x01: 441 return MAN_SPANSION; 442 case 0xC2: 443 return MAN_MACRONIX; 444 default: 445 return MAN_GENERIC; 446 } 447 } 448 449 static void blk_sync_complete(void *opaque, int ret) 450 { 451 QEMUIOVector *iov = opaque; 452 453 qemu_iovec_destroy(iov); 454 g_free(iov); 455 456 /* do nothing. Masters do not directly interact with the backing store, 457 * only the working copy so no mutexing required. 458 */ 459 } 460 461 static void flash_sync_page(Flash *s, int page) 462 { 463 QEMUIOVector *iov; 464 465 if (!s->blk || blk_is_read_only(s->blk)) { 466 return; 467 } 468 469 iov = g_new(QEMUIOVector, 1); 470 qemu_iovec_init(iov, 1); 471 qemu_iovec_add(iov, s->storage + page * s->pi->page_size, 472 s->pi->page_size); 473 blk_aio_pwritev(s->blk, page * s->pi->page_size, iov, 0, 474 blk_sync_complete, iov); 475 } 476 477 static inline void flash_sync_area(Flash *s, int64_t off, int64_t len) 478 { 479 QEMUIOVector *iov; 480 481 if (!s->blk || blk_is_read_only(s->blk)) { 482 return; 483 } 484 485 assert(!(len % BDRV_SECTOR_SIZE)); 486 iov = g_new(QEMUIOVector, 1); 487 qemu_iovec_init(iov, 1); 488 qemu_iovec_add(iov, s->storage + off, len); 489 blk_aio_pwritev(s->blk, off, iov, 0, blk_sync_complete, iov); 490 } 491 492 static void flash_erase(Flash *s, int offset, FlashCMD cmd) 493 { 494 uint32_t len; 495 uint8_t capa_to_assert = 0; 496 497 switch (cmd) { 498 case ERASE_4K: 499 case ERASE4_4K: 500 len = 4 << 10; 501 capa_to_assert = ER_4K; 502 break; 503 case ERASE_32K: 504 case ERASE4_32K: 505 len = 32 << 10; 506 capa_to_assert = ER_32K; 507 break; 508 case ERASE_SECTOR: 509 case ERASE4_SECTOR: 510 len = s->pi->sector_size; 511 break; 512 case BULK_ERASE: 513 len = s->size; 514 break; 515 default: 516 abort(); 517 } 518 519 DB_PRINT_L(0, "offset = %#x, len = %d\n", offset, len); 520 if ((s->pi->flags & capa_to_assert) != capa_to_assert) { 521 qemu_log_mask(LOG_GUEST_ERROR, "M25P80: %d erase size not supported by" 522 " device\n", len); 523 } 524 525 if (!s->write_enable) { 526 qemu_log_mask(LOG_GUEST_ERROR, "M25P80: erase with write protect!\n"); 527 return; 528 } 529 memset(s->storage + offset, 0xff, len); 530 flash_sync_area(s, offset, len); 531 } 532 533 static inline void flash_sync_dirty(Flash *s, int64_t newpage) 534 { 535 if (s->dirty_page >= 0 && s->dirty_page != newpage) { 536 flash_sync_page(s, s->dirty_page); 537 s->dirty_page = newpage; 538 } 539 } 540 541 static inline 542 void flash_write8(Flash *s, uint32_t addr, uint8_t data) 543 { 544 uint32_t page = addr / s->pi->page_size; 545 uint8_t prev = s->storage[s->cur_addr]; 546 547 if (!s->write_enable) { 548 qemu_log_mask(LOG_GUEST_ERROR, "M25P80: write with write protect!\n"); 549 } 550 551 if ((prev ^ data) & data) { 552 DB_PRINT_L(1, "programming zero to one! addr=%" PRIx32 " %" PRIx8 553 " -> %" PRIx8 "\n", addr, prev, data); 554 } 555 556 if (s->pi->flags & EEPROM) { 557 s->storage[s->cur_addr] = data; 558 } else { 559 s->storage[s->cur_addr] &= data; 560 } 561 562 flash_sync_dirty(s, page); 563 s->dirty_page = page; 564 } 565 566 static inline int get_addr_length(Flash *s) 567 { 568 /* check if eeprom is in use */ 569 if (s->pi->flags == EEPROM) { 570 return 2; 571 } 572 573 switch (s->cmd_in_progress) { 574 case PP4: 575 case PP4_4: 576 case READ4: 577 case QIOR4: 578 case ERASE4_4K: 579 case ERASE4_32K: 580 case ERASE4_SECTOR: 581 case FAST_READ4: 582 case DOR4: 583 case QOR4: 584 case DIOR4: 585 return 4; 586 default: 587 return s->four_bytes_address_mode ? 4 : 3; 588 } 589 } 590 591 static void complete_collecting_data(Flash *s) 592 { 593 int i, n; 594 595 n = get_addr_length(s); 596 s->cur_addr = (n == 3 ? s->ear : 0); 597 for (i = 0; i < n; ++i) { 598 s->cur_addr <<= 8; 599 s->cur_addr |= s->data[i]; 600 } 601 602 s->cur_addr &= s->size - 1; 603 604 s->state = STATE_IDLE; 605 606 switch (s->cmd_in_progress) { 607 case DPP: 608 case QPP: 609 case PP: 610 case PP4: 611 case PP4_4: 612 s->state = STATE_PAGE_PROGRAM; 613 break; 614 case READ: 615 case READ4: 616 case FAST_READ: 617 case FAST_READ4: 618 case DOR: 619 case DOR4: 620 case QOR: 621 case QOR4: 622 case DIOR: 623 case DIOR4: 624 case QIOR: 625 case QIOR4: 626 s->state = STATE_READ; 627 break; 628 case ERASE_4K: 629 case ERASE4_4K: 630 case ERASE_32K: 631 case ERASE4_32K: 632 case ERASE_SECTOR: 633 case ERASE4_SECTOR: 634 flash_erase(s, s->cur_addr, s->cmd_in_progress); 635 break; 636 case WRSR: 637 switch (get_man(s)) { 638 case MAN_SPANSION: 639 s->quad_enable = !!(s->data[1] & 0x02); 640 break; 641 case MAN_MACRONIX: 642 s->quad_enable = extract32(s->data[0], 6, 1); 643 if (s->len > 1) { 644 s->four_bytes_address_mode = extract32(s->data[1], 5, 1); 645 } 646 break; 647 default: 648 break; 649 } 650 if (s->write_enable) { 651 s->write_enable = false; 652 } 653 break; 654 case EXTEND_ADDR_WRITE: 655 s->ear = s->data[0]; 656 break; 657 case WNVCR: 658 s->nonvolatile_cfg = s->data[0] | (s->data[1] << 8); 659 break; 660 case WVCR: 661 s->volatile_cfg = s->data[0]; 662 break; 663 case WEVCR: 664 s->enh_volatile_cfg = s->data[0]; 665 break; 666 default: 667 break; 668 } 669 } 670 671 static void reset_memory(Flash *s) 672 { 673 s->cmd_in_progress = NOP; 674 s->cur_addr = 0; 675 s->ear = 0; 676 s->four_bytes_address_mode = false; 677 s->len = 0; 678 s->needed_bytes = 0; 679 s->pos = 0; 680 s->state = STATE_IDLE; 681 s->write_enable = false; 682 s->reset_enable = false; 683 s->quad_enable = false; 684 685 switch (get_man(s)) { 686 case MAN_NUMONYX: 687 s->volatile_cfg = 0; 688 s->volatile_cfg |= VCFG_DUMMY; 689 s->volatile_cfg |= VCFG_WRAP_SEQUENTIAL; 690 if ((s->nonvolatile_cfg & NVCFG_XIP_MODE_MASK) 691 != NVCFG_XIP_MODE_DISABLED) { 692 s->volatile_cfg |= VCFG_XIP_MODE_ENABLED; 693 } 694 s->volatile_cfg |= deposit32(s->volatile_cfg, 695 VCFG_DUMMY_CLK_POS, 696 CFG_DUMMY_CLK_LEN, 697 extract32(s->nonvolatile_cfg, 698 NVCFG_DUMMY_CLK_POS, 699 CFG_DUMMY_CLK_LEN) 700 ); 701 702 s->enh_volatile_cfg = 0; 703 s->enh_volatile_cfg |= EVCFG_OUT_DRIVER_STRENGHT_DEF; 704 s->enh_volatile_cfg |= EVCFG_VPP_ACCELERATOR; 705 s->enh_volatile_cfg |= EVCFG_RESET_HOLD_ENABLED; 706 if (s->nonvolatile_cfg & NVCFG_DUAL_IO_MASK) { 707 s->enh_volatile_cfg |= EVCFG_DUAL_IO_ENABLED; 708 } 709 if (s->nonvolatile_cfg & NVCFG_QUAD_IO_MASK) { 710 s->enh_volatile_cfg |= EVCFG_QUAD_IO_ENABLED; 711 } 712 if (!(s->nonvolatile_cfg & NVCFG_4BYTE_ADDR_MASK)) { 713 s->four_bytes_address_mode = true; 714 } 715 if (!(s->nonvolatile_cfg & NVCFG_LOWER_SEGMENT_MASK)) { 716 s->ear = s->size / MAX_3BYTES_SIZE - 1; 717 } 718 break; 719 case MAN_MACRONIX: 720 s->volatile_cfg = 0x7; 721 break; 722 case MAN_SPANSION: 723 s->spansion_cr1v = s->spansion_cr1nv; 724 s->spansion_cr2v = s->spansion_cr2nv; 725 s->spansion_cr3v = s->spansion_cr3nv; 726 s->spansion_cr4v = s->spansion_cr4nv; 727 s->quad_enable = extract32(s->spansion_cr1v, 728 SPANSION_QUAD_CFG_POS, 729 SPANSION_QUAD_CFG_LEN 730 ); 731 s->four_bytes_address_mode = extract32(s->spansion_cr2v, 732 SPANSION_ADDR_LEN_POS, 733 SPANSION_ADDR_LEN_LEN 734 ); 735 break; 736 default: 737 break; 738 } 739 740 DB_PRINT_L(0, "Reset done.\n"); 741 } 742 743 static void decode_fast_read_cmd(Flash *s) 744 { 745 s->needed_bytes = get_addr_length(s); 746 switch (get_man(s)) { 747 /* Dummy cycles - modeled with bytes writes instead of bits */ 748 case MAN_WINBOND: 749 s->needed_bytes += 8; 750 break; 751 case MAN_NUMONYX: 752 s->needed_bytes += extract32(s->volatile_cfg, 4, 4); 753 break; 754 case MAN_MACRONIX: 755 if (extract32(s->volatile_cfg, 6, 2) == 1) { 756 s->needed_bytes += 6; 757 } else { 758 s->needed_bytes += 8; 759 } 760 break; 761 case MAN_SPANSION: 762 s->needed_bytes += extract32(s->spansion_cr2v, 763 SPANSION_DUMMY_CLK_POS, 764 SPANSION_DUMMY_CLK_LEN 765 ); 766 break; 767 default: 768 break; 769 } 770 s->pos = 0; 771 s->len = 0; 772 s->state = STATE_COLLECTING_DATA; 773 } 774 775 static void decode_dio_read_cmd(Flash *s) 776 { 777 s->needed_bytes = get_addr_length(s); 778 /* Dummy cycles modeled with bytes writes instead of bits */ 779 switch (get_man(s)) { 780 case MAN_WINBOND: 781 s->needed_bytes += WINBOND_CONTINUOUS_READ_MODE_CMD_LEN; 782 break; 783 case MAN_SPANSION: 784 s->needed_bytes += SPANSION_CONTINUOUS_READ_MODE_CMD_LEN; 785 s->needed_bytes += extract32(s->spansion_cr2v, 786 SPANSION_DUMMY_CLK_POS, 787 SPANSION_DUMMY_CLK_LEN 788 ); 789 break; 790 case MAN_NUMONYX: 791 s->needed_bytes += extract32(s->volatile_cfg, 4, 4); 792 break; 793 case MAN_MACRONIX: 794 switch (extract32(s->volatile_cfg, 6, 2)) { 795 case 1: 796 s->needed_bytes += 6; 797 break; 798 case 2: 799 s->needed_bytes += 8; 800 break; 801 default: 802 s->needed_bytes += 4; 803 break; 804 } 805 break; 806 default: 807 break; 808 } 809 s->pos = 0; 810 s->len = 0; 811 s->state = STATE_COLLECTING_DATA; 812 } 813 814 static void decode_qio_read_cmd(Flash *s) 815 { 816 s->needed_bytes = get_addr_length(s); 817 /* Dummy cycles modeled with bytes writes instead of bits */ 818 switch (get_man(s)) { 819 case MAN_WINBOND: 820 s->needed_bytes += WINBOND_CONTINUOUS_READ_MODE_CMD_LEN; 821 s->needed_bytes += 4; 822 break; 823 case MAN_SPANSION: 824 s->needed_bytes += SPANSION_CONTINUOUS_READ_MODE_CMD_LEN; 825 s->needed_bytes += extract32(s->spansion_cr2v, 826 SPANSION_DUMMY_CLK_POS, 827 SPANSION_DUMMY_CLK_LEN 828 ); 829 break; 830 case MAN_NUMONYX: 831 s->needed_bytes += extract32(s->volatile_cfg, 4, 4); 832 break; 833 case MAN_MACRONIX: 834 switch (extract32(s->volatile_cfg, 6, 2)) { 835 case 1: 836 s->needed_bytes += 4; 837 break; 838 case 2: 839 s->needed_bytes += 8; 840 break; 841 default: 842 s->needed_bytes += 6; 843 break; 844 } 845 break; 846 default: 847 break; 848 } 849 s->pos = 0; 850 s->len = 0; 851 s->state = STATE_COLLECTING_DATA; 852 } 853 854 static void decode_new_cmd(Flash *s, uint32_t value) 855 { 856 s->cmd_in_progress = value; 857 int i; 858 DB_PRINT_L(0, "decoded new command:%x\n", value); 859 860 if (value != RESET_MEMORY) { 861 s->reset_enable = false; 862 } 863 864 switch (value) { 865 866 case ERASE_4K: 867 case ERASE4_4K: 868 case ERASE_32K: 869 case ERASE4_32K: 870 case ERASE_SECTOR: 871 case ERASE4_SECTOR: 872 case READ: 873 case READ4: 874 case DPP: 875 case QPP: 876 case PP: 877 case PP4: 878 case PP4_4: 879 s->needed_bytes = get_addr_length(s); 880 s->pos = 0; 881 s->len = 0; 882 s->state = STATE_COLLECTING_DATA; 883 break; 884 885 case FAST_READ: 886 case FAST_READ4: 887 case DOR: 888 case DOR4: 889 case QOR: 890 case QOR4: 891 decode_fast_read_cmd(s); 892 break; 893 894 case DIOR: 895 case DIOR4: 896 decode_dio_read_cmd(s); 897 break; 898 899 case QIOR: 900 case QIOR4: 901 decode_qio_read_cmd(s); 902 break; 903 904 case WRSR: 905 if (s->write_enable) { 906 switch (get_man(s)) { 907 case MAN_SPANSION: 908 s->needed_bytes = 2; 909 s->state = STATE_COLLECTING_DATA; 910 break; 911 case MAN_MACRONIX: 912 s->needed_bytes = 2; 913 s->state = STATE_COLLECTING_VAR_LEN_DATA; 914 break; 915 default: 916 s->needed_bytes = 1; 917 s->state = STATE_COLLECTING_DATA; 918 } 919 s->pos = 0; 920 } 921 break; 922 923 case WRDI: 924 s->write_enable = false; 925 break; 926 case WREN: 927 s->write_enable = true; 928 break; 929 930 case RDSR: 931 s->data[0] = (!!s->write_enable) << 1; 932 if (get_man(s) == MAN_MACRONIX) { 933 s->data[0] |= (!!s->quad_enable) << 6; 934 } 935 s->pos = 0; 936 s->len = 1; 937 s->state = STATE_READING_DATA; 938 break; 939 940 case READ_FSR: 941 s->data[0] = FSR_FLASH_READY; 942 if (s->four_bytes_address_mode) { 943 s->data[0] |= FSR_4BYTE_ADDR_MODE_ENABLED; 944 } 945 s->pos = 0; 946 s->len = 1; 947 s->state = STATE_READING_DATA; 948 break; 949 950 case JEDEC_READ: 951 DB_PRINT_L(0, "populated jedec code\n"); 952 for (i = 0; i < s->pi->id_len; i++) { 953 s->data[i] = s->pi->id[i]; 954 } 955 956 s->len = s->pi->id_len; 957 s->pos = 0; 958 s->state = STATE_READING_DATA; 959 break; 960 961 case RDCR: 962 s->data[0] = s->volatile_cfg & 0xFF; 963 s->data[0] |= (!!s->four_bytes_address_mode) << 5; 964 s->pos = 0; 965 s->len = 1; 966 s->state = STATE_READING_DATA; 967 break; 968 969 case BULK_ERASE: 970 if (s->write_enable) { 971 DB_PRINT_L(0, "chip erase\n"); 972 flash_erase(s, 0, BULK_ERASE); 973 } else { 974 qemu_log_mask(LOG_GUEST_ERROR, "M25P80: chip erase with write " 975 "protect!\n"); 976 } 977 break; 978 case NOP: 979 break; 980 case EN_4BYTE_ADDR: 981 s->four_bytes_address_mode = true; 982 break; 983 case EX_4BYTE_ADDR: 984 s->four_bytes_address_mode = false; 985 break; 986 case EXTEND_ADDR_READ: 987 s->data[0] = s->ear; 988 s->pos = 0; 989 s->len = 1; 990 s->state = STATE_READING_DATA; 991 break; 992 case EXTEND_ADDR_WRITE: 993 if (s->write_enable) { 994 s->needed_bytes = 1; 995 s->pos = 0; 996 s->len = 0; 997 s->state = STATE_COLLECTING_DATA; 998 } 999 break; 1000 case RNVCR: 1001 s->data[0] = s->nonvolatile_cfg & 0xFF; 1002 s->data[1] = (s->nonvolatile_cfg >> 8) & 0xFF; 1003 s->pos = 0; 1004 s->len = 2; 1005 s->state = STATE_READING_DATA; 1006 break; 1007 case WNVCR: 1008 if (s->write_enable && get_man(s) == MAN_NUMONYX) { 1009 s->needed_bytes = 2; 1010 s->pos = 0; 1011 s->len = 0; 1012 s->state = STATE_COLLECTING_DATA; 1013 } 1014 break; 1015 case RVCR: 1016 s->data[0] = s->volatile_cfg & 0xFF; 1017 s->pos = 0; 1018 s->len = 1; 1019 s->state = STATE_READING_DATA; 1020 break; 1021 case WVCR: 1022 if (s->write_enable) { 1023 s->needed_bytes = 1; 1024 s->pos = 0; 1025 s->len = 0; 1026 s->state = STATE_COLLECTING_DATA; 1027 } 1028 break; 1029 case REVCR: 1030 s->data[0] = s->enh_volatile_cfg & 0xFF; 1031 s->pos = 0; 1032 s->len = 1; 1033 s->state = STATE_READING_DATA; 1034 break; 1035 case WEVCR: 1036 if (s->write_enable) { 1037 s->needed_bytes = 1; 1038 s->pos = 0; 1039 s->len = 0; 1040 s->state = STATE_COLLECTING_DATA; 1041 } 1042 break; 1043 case RESET_ENABLE: 1044 s->reset_enable = true; 1045 break; 1046 case RESET_MEMORY: 1047 if (s->reset_enable) { 1048 reset_memory(s); 1049 } 1050 break; 1051 case RDCR_EQIO: 1052 switch (get_man(s)) { 1053 case MAN_SPANSION: 1054 s->data[0] = (!!s->quad_enable) << 1; 1055 s->pos = 0; 1056 s->len = 1; 1057 s->state = STATE_READING_DATA; 1058 break; 1059 case MAN_MACRONIX: 1060 s->quad_enable = true; 1061 break; 1062 default: 1063 break; 1064 } 1065 break; 1066 case RSTQIO: 1067 s->quad_enable = false; 1068 break; 1069 default: 1070 qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Unknown cmd %x\n", value); 1071 break; 1072 } 1073 } 1074 1075 static int m25p80_cs(SSISlave *ss, bool select) 1076 { 1077 Flash *s = M25P80(ss); 1078 1079 if (select) { 1080 if (s->state == STATE_COLLECTING_VAR_LEN_DATA) { 1081 complete_collecting_data(s); 1082 } 1083 s->len = 0; 1084 s->pos = 0; 1085 s->state = STATE_IDLE; 1086 flash_sync_dirty(s, -1); 1087 } 1088 1089 DB_PRINT_L(0, "%sselect\n", select ? "de" : ""); 1090 1091 return 0; 1092 } 1093 1094 static uint32_t m25p80_transfer8(SSISlave *ss, uint32_t tx) 1095 { 1096 Flash *s = M25P80(ss); 1097 uint32_t r = 0; 1098 1099 switch (s->state) { 1100 1101 case STATE_PAGE_PROGRAM: 1102 DB_PRINT_L(1, "page program cur_addr=%#" PRIx32 " data=%" PRIx8 "\n", 1103 s->cur_addr, (uint8_t)tx); 1104 flash_write8(s, s->cur_addr, (uint8_t)tx); 1105 s->cur_addr = (s->cur_addr + 1) & (s->size - 1); 1106 break; 1107 1108 case STATE_READ: 1109 r = s->storage[s->cur_addr]; 1110 DB_PRINT_L(1, "READ 0x%" PRIx32 "=%" PRIx8 "\n", s->cur_addr, 1111 (uint8_t)r); 1112 s->cur_addr = (s->cur_addr + 1) & (s->size - 1); 1113 break; 1114 1115 case STATE_COLLECTING_DATA: 1116 case STATE_COLLECTING_VAR_LEN_DATA: 1117 s->data[s->len] = (uint8_t)tx; 1118 s->len++; 1119 1120 if (s->len == s->needed_bytes) { 1121 complete_collecting_data(s); 1122 } 1123 break; 1124 1125 case STATE_READING_DATA: 1126 r = s->data[s->pos]; 1127 s->pos++; 1128 if (s->pos == s->len) { 1129 s->pos = 0; 1130 s->state = STATE_IDLE; 1131 } 1132 break; 1133 1134 default: 1135 case STATE_IDLE: 1136 decode_new_cmd(s, (uint8_t)tx); 1137 break; 1138 } 1139 1140 return r; 1141 } 1142 1143 static void m25p80_realize(SSISlave *ss, Error **errp) 1144 { 1145 Flash *s = M25P80(ss); 1146 M25P80Class *mc = M25P80_GET_CLASS(s); 1147 1148 s->pi = mc->pi; 1149 1150 s->size = s->pi->sector_size * s->pi->n_sectors; 1151 s->dirty_page = -1; 1152 1153 if (s->blk) { 1154 DB_PRINT_L(0, "Binding to IF_MTD drive\n"); 1155 s->storage = blk_blockalign(s->blk, s->size); 1156 1157 if (blk_pread(s->blk, 0, s->storage, s->size) != s->size) { 1158 error_setg(errp, "failed to read the initial flash content"); 1159 return; 1160 } 1161 } else { 1162 DB_PRINT_L(0, "No BDRV - binding to RAM\n"); 1163 s->storage = blk_blockalign(NULL, s->size); 1164 memset(s->storage, 0xFF, s->size); 1165 } 1166 } 1167 1168 static void m25p80_reset(DeviceState *d) 1169 { 1170 Flash *s = M25P80(d); 1171 1172 reset_memory(s); 1173 } 1174 1175 static void m25p80_pre_save(void *opaque) 1176 { 1177 flash_sync_dirty((Flash *)opaque, -1); 1178 } 1179 1180 static Property m25p80_properties[] = { 1181 /* This is default value for Micron flash */ 1182 DEFINE_PROP_UINT32("nonvolatile-cfg", Flash, nonvolatile_cfg, 0x8FFF), 1183 DEFINE_PROP_UINT8("spansion-cr1nv", Flash, spansion_cr1nv, 0x0), 1184 DEFINE_PROP_UINT8("spansion-cr2nv", Flash, spansion_cr2nv, 0x8), 1185 DEFINE_PROP_UINT8("spansion-cr3nv", Flash, spansion_cr3nv, 0x2), 1186 DEFINE_PROP_UINT8("spansion-cr4nv", Flash, spansion_cr4nv, 0x10), 1187 DEFINE_PROP_DRIVE("drive", Flash, blk), 1188 DEFINE_PROP_END_OF_LIST(), 1189 }; 1190 1191 static const VMStateDescription vmstate_m25p80 = { 1192 .name = "m25p80", 1193 .version_id = 0, 1194 .minimum_version_id = 0, 1195 .pre_save = m25p80_pre_save, 1196 .fields = (VMStateField[]) { 1197 VMSTATE_UINT8(state, Flash), 1198 VMSTATE_UINT8_ARRAY(data, Flash, 16), 1199 VMSTATE_UINT32(len, Flash), 1200 VMSTATE_UINT32(pos, Flash), 1201 VMSTATE_UINT8(needed_bytes, Flash), 1202 VMSTATE_UINT8(cmd_in_progress, Flash), 1203 VMSTATE_UINT32(cur_addr, Flash), 1204 VMSTATE_BOOL(write_enable, Flash), 1205 VMSTATE_BOOL(reset_enable, Flash), 1206 VMSTATE_UINT8(ear, Flash), 1207 VMSTATE_BOOL(four_bytes_address_mode, Flash), 1208 VMSTATE_UINT32(nonvolatile_cfg, Flash), 1209 VMSTATE_UINT32(volatile_cfg, Flash), 1210 VMSTATE_UINT32(enh_volatile_cfg, Flash), 1211 VMSTATE_BOOL(quad_enable, Flash), 1212 VMSTATE_UINT8(spansion_cr1nv, Flash), 1213 VMSTATE_UINT8(spansion_cr2nv, Flash), 1214 VMSTATE_UINT8(spansion_cr3nv, Flash), 1215 VMSTATE_UINT8(spansion_cr4nv, Flash), 1216 VMSTATE_END_OF_LIST() 1217 } 1218 }; 1219 1220 static void m25p80_class_init(ObjectClass *klass, void *data) 1221 { 1222 DeviceClass *dc = DEVICE_CLASS(klass); 1223 SSISlaveClass *k = SSI_SLAVE_CLASS(klass); 1224 M25P80Class *mc = M25P80_CLASS(klass); 1225 1226 k->realize = m25p80_realize; 1227 k->transfer = m25p80_transfer8; 1228 k->set_cs = m25p80_cs; 1229 k->cs_polarity = SSI_CS_LOW; 1230 dc->vmsd = &vmstate_m25p80; 1231 dc->props = m25p80_properties; 1232 dc->reset = m25p80_reset; 1233 mc->pi = data; 1234 } 1235 1236 static const TypeInfo m25p80_info = { 1237 .name = TYPE_M25P80, 1238 .parent = TYPE_SSI_SLAVE, 1239 .instance_size = sizeof(Flash), 1240 .class_size = sizeof(M25P80Class), 1241 .abstract = true, 1242 }; 1243 1244 static void m25p80_register_types(void) 1245 { 1246 int i; 1247 1248 type_register_static(&m25p80_info); 1249 for (i = 0; i < ARRAY_SIZE(known_devices); ++i) { 1250 TypeInfo ti = { 1251 .name = known_devices[i].part_name, 1252 .parent = TYPE_M25P80, 1253 .class_init = m25p80_class_init, 1254 .class_data = (void *)&known_devices[i], 1255 }; 1256 type_register(&ti); 1257 } 1258 } 1259 1260 type_init(m25p80_register_types) 1261