diff options
Diffstat (limited to 'hw/block/m25p80.c')
-rw-r--r-- | hw/block/m25p80.c | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c index 0412d3e7f4..5f9471d83c 100644 --- a/hw/block/m25p80.c +++ b/hw/block/m25p80.c @@ -210,6 +210,19 @@ static const FlashPartInfo known_devices[] = { { INFO("640s33b", 0x898913, 0, 64 << 10, 128, 0) }, { INFO("n25q064", 0x20ba17, 0, 64 << 10, 128, 0) }, + /* ISSI */ + { INFO("is25lq040b", 0x9d4013, 0, 64 << 10, 8, ER_4K) }, + { INFO("is25lp080d", 0x9d6014, 0, 64 << 10, 16, ER_4K) }, + { INFO("is25lp016d", 0x9d6015, 0, 64 << 10, 32, ER_4K) }, + { INFO("is25lp032", 0x9d6016, 0, 64 << 10, 64, ER_4K) }, + { INFO("is25lp064", 0x9d6017, 0, 64 << 10, 128, ER_4K) }, + { INFO("is25lp128", 0x9d6018, 0, 64 << 10, 256, ER_4K) }, + { INFO("is25lp256", 0x9d6019, 0, 64 << 10, 512, ER_4K) }, + { INFO("is25wp032", 0x9d7016, 0, 64 << 10, 64, ER_4K) }, + { INFO("is25wp064", 0x9d7017, 0, 64 << 10, 128, ER_4K) }, + { INFO("is25wp128", 0x9d7018, 0, 64 << 10, 256, ER_4K) }, + { INFO("is25wp256", 0x9d7019, 0, 64 << 10, 512, ER_4K) }, + /* Macronix */ { INFO("mx25l2005a", 0xc22012, 0, 64 << 10, 4, ER_4K) }, { INFO("mx25l4005a", 0xc22013, 0, 64 << 10, 8, ER_4K) }, @@ -412,6 +425,7 @@ typedef enum { MAN_NUMONYX, MAN_WINBOND, MAN_SST, + MAN_ISSI, MAN_GENERIC, } Manufacturer; @@ -487,6 +501,8 @@ static inline Manufacturer get_man(Flash *s) return MAN_MACRONIX; case 0xBF: return MAN_SST; + case 0x9D: + return MAN_ISSI; default: return MAN_GENERIC; } @@ -706,6 +722,9 @@ static void complete_collecting_data(Flash *s) case MAN_SPANSION: s->quad_enable = !!(s->data[1] & 0x02); break; + case MAN_ISSI: + s->quad_enable = extract32(s->data[0], 6, 1); + break; case MAN_MACRONIX: s->quad_enable = extract32(s->data[0], 6, 1); if (s->len > 1) { @@ -895,6 +914,19 @@ static void decode_fast_read_cmd(Flash *s) SPANSION_DUMMY_CLK_LEN ); break; + case MAN_ISSI: + /* + * The Fast Read instruction code is followed by address bytes and + * dummy cycles, transmitted via the SI line. + * + * The number of dummy cycles is configurable but this is currently + * unmodeled, hence the default value 8 is used. + * + * QPI (Quad Peripheral Interface) mode has different default value + * of dummy cycles, but this is unsupported at the time being. + */ + s->needed_bytes += 1; + break; default: break; } @@ -934,6 +966,16 @@ static void decode_dio_read_cmd(Flash *s) break; } break; + case MAN_ISSI: + /* + * The Fast Read Dual I/O instruction code is followed by address bytes + * and dummy cycles, transmitted via the IO1 and IO0 line. + * + * The number of dummy cycles is configurable but this is currently + * unmodeled, hence the default value 4 is used. + */ + s->needed_bytes += 1; + break; default: break; } @@ -974,6 +1016,19 @@ static void decode_qio_read_cmd(Flash *s) break; } break; + case MAN_ISSI: + /* + * The Fast Read Quad I/O instruction code is followed by address bytes + * and dummy cycles, transmitted via the IO3, IO2, IO1 and IO0 line. + * + * The number of dummy cycles is configurable but this is currently + * unmodeled, hence the default value 6 is used. + * + * QPI (Quad Peripheral Interface) mode has different default value + * of dummy cycles, but this is unsupported at the time being. + */ + s->needed_bytes += 3; + break; default: break; } @@ -1132,7 +1187,7 @@ static void decode_new_cmd(Flash *s, uint32_t value) case RDSR: s->data[0] = (!!s->write_enable) << 1; - if (get_man(s) == MAN_MACRONIX) { + if (get_man(s) == MAN_MACRONIX || get_man(s) == MAN_ISSI) { s->data[0] |= (!!s->quad_enable) << 6; } if (get_man(s) == MAN_SST) { |