Skip to content

Commit 56de0e8

Browse files
m25p80: fix ISSI QE handling and QIO dummy bytes for 0xEB
1 parent 7b7b976 commit 56de0e8

1 file changed

Lines changed: 71 additions & 12 deletions

File tree

hw/block/m25p80.c

Lines changed: 71 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,8 @@ struct Flash {
514514
bool four_bytes_address_mode;
515515
bool reset_enable;
516516
bool quad_enable;
517+
uint8_t status_reg1_raw;
518+
uint8_t status_reg2;
517519
bool aai_enable;
518520
bool block_protect0;
519521
bool block_protect1;
@@ -810,9 +812,22 @@ static void complete_collecting_data(Flash *s)
810812
case MAN_SPANSION:
811813
s->quad_enable = !!(s->data[1] & 0x02);
812814
break;
813-
case MAN_ISSI:
814-
s->quad_enable = extract32(s->data[0], 6, 1);
815+
case MAN_ISSI: {
816+
bool qe_sr1_bit6;
817+
bool qe_sr1_bit1;
818+
bool qe_sr2_bit1;
819+
820+
s->status_reg1_raw = s->data[0];
821+
if (s->len > 1) {
822+
s->status_reg2 = s->data[1];
823+
}
824+
825+
qe_sr1_bit6 = extract32(s->status_reg1_raw, 6, 1);
826+
qe_sr1_bit1 = extract32(s->status_reg1_raw, 1, 1);
827+
qe_sr2_bit1 = extract32(s->status_reg2, 1, 1);
828+
s->quad_enable = qe_sr1_bit6 || qe_sr1_bit1 || qe_sr2_bit1;
815829
break;
830+
}
816831
case MAN_MACRONIX:
817832
s->quad_enable = extract32(s->data[0], 6, 1);
818833
if (s->len > 1) {
@@ -837,6 +852,17 @@ static void complete_collecting_data(Flash *s)
837852
case MAN_WINBOND:
838853
s->quad_enable = !!(s->data[0] & 0x02);
839854
break;
855+
case MAN_ISSI: {
856+
bool qe_sr1_bit6;
857+
bool qe_sr1_bit1;
858+
859+
s->status_reg2 = s->data[0];
860+
qe_sr1_bit6 = extract32(s->status_reg1_raw, 6, 1);
861+
qe_sr1_bit1 = extract32(s->status_reg1_raw, 1, 1);
862+
s->quad_enable = extract32(s->status_reg2, 1, 1) ||
863+
qe_sr1_bit6 || qe_sr1_bit1;
864+
break;
865+
}
840866
default:
841867
break;
842868
}
@@ -902,6 +928,8 @@ static void reset_memory(Flash *s)
902928
s->write_enable = false;
903929
s->reset_enable = false;
904930
s->quad_enable = false;
931+
s->status_reg1_raw = 0;
932+
s->status_reg2 = 0;
905933
s->aai_enable = false;
906934

907935
switch (get_man(s)) {
@@ -1132,16 +1160,14 @@ static void decode_qio_read_cmd(Flash *s)
11321160
break;
11331161
case MAN_ISSI:
11341162
/*
1135-
* The Fast Read Quad I/O instruction code is followed by address bytes
1136-
* and dummy cycles, transmitted via the IO3, IO2, IO1 and IO0 line.
1163+
* The Fast Read Quad I/O instruction code is followed by address bytes,
1164+
* one mode byte, and one dummy byte (8 dummy cycles) on the IO3..IO0
1165+
* lines for 0xEB on ESP32S3. Model mode+dummy as 2 extra bytes.
11371166
*
1138-
* The number of dummy cycles is configurable but this is currently
1139-
* unmodeled, hence the default value 6 is used.
1140-
*
1141-
* QPI (Quad Peripheral Interface) mode has different default value
1142-
* of dummy cycles, but this is unsupported at the time being.
1167+
* QPI (Quad Peripheral Interface) mode has different default values,
1168+
* but this is unsupported at the time being.
11431169
*/
1144-
s->needed_bytes += 3;
1170+
s->needed_bytes += 2;
11451171
break;
11461172
default:
11471173
break;
@@ -1298,6 +1324,10 @@ static void decode_new_cmd(Flash *s, uint32_t value)
12981324
s->needed_bytes = 2;
12991325
s->state = STATE_COLLECTING_VAR_LEN_DATA;
13001326
break;
1327+
case MAN_ISSI:
1328+
s->needed_bytes = 2;
1329+
s->state = STATE_COLLECTING_VAR_LEN_DATA;
1330+
break;
13011331
default:
13021332
s->needed_bytes = 1;
13031333
s->state = STATE_COLLECTING_DATA;
@@ -1321,6 +1351,7 @@ static void decode_new_cmd(Flash *s, uint32_t value)
13211351

13221352
switch (get_man(s)) {
13231353
case MAN_WINBOND:
1354+
case MAN_ISSI:
13241355
s->needed_bytes = 1;
13251356
s->state = STATE_COLLECTING_DATA;
13261357
s->pos = 0;
@@ -1396,8 +1427,25 @@ static void decode_new_cmd(Flash *s, uint32_t value)
13961427
break;
13971428

13981429
case RDCR:
1399-
s->data[0] = s->volatile_cfg & 0xFF;
1400-
s->data[0] |= (!!s->four_bytes_address_mode) << 5;
1430+
switch (get_man(s)) {
1431+
case MAN_ISSI:
1432+
s->data[0] = s->status_reg2;
1433+
s->quad_enable = !!(s->status_reg2 & 0x02) ||
1434+
!!(s->status_reg1_raw & 0x40) ||
1435+
!!(s->status_reg1_raw & 0x02);
1436+
break;
1437+
case MAN_SPANSION:
1438+
s->data[0] = s->spansion_cr1v;
1439+
s->quad_enable = extract32(s->spansion_cr1v,
1440+
SPANSION_QUAD_CFG_POS,
1441+
SPANSION_QUAD_CFG_LEN);
1442+
break;
1443+
case MAN_MACRONIX:
1444+
default:
1445+
s->data[0] = s->volatile_cfg & 0xFF;
1446+
s->data[0] |= (!!s->four_bytes_address_mode) << 5;
1447+
break;
1448+
}
14011449
s->pos = 0;
14021450
s->len = 1;
14031451
s->state = STATE_READING_DATA;
@@ -1505,6 +1553,15 @@ static void decode_new_cmd(Flash *s, uint32_t value)
15051553
s->len = 1;
15061554
s->state = STATE_READING_DATA;
15071555
break;
1556+
case MAN_ISSI:
1557+
s->data[0] = s->status_reg2;
1558+
s->quad_enable = !!(s->status_reg2 & 0x02) ||
1559+
!!(s->status_reg1_raw & 0x40) ||
1560+
!!(s->status_reg1_raw & 0x02);
1561+
s->pos = 0;
1562+
s->len = 1;
1563+
s->state = STATE_READING_DATA;
1564+
break;
15081565
default:
15091566
break;
15101567
}
@@ -1852,6 +1909,8 @@ static const VMStateDescription vmstate_m25p80 = {
18521909
VMSTATE_UINT32(volatile_cfg, Flash),
18531910
VMSTATE_UINT32(enh_volatile_cfg, Flash),
18541911
VMSTATE_BOOL(quad_enable, Flash),
1912+
VMSTATE_UINT8(status_reg1_raw, Flash),
1913+
VMSTATE_UINT8(status_reg2, Flash),
18551914
VMSTATE_UINT8(spansion_cr1nv, Flash),
18561915
VMSTATE_UINT8(spansion_cr2nv, Flash),
18571916
VMSTATE_UINT8(spansion_cr3nv, Flash),

0 commit comments

Comments
 (0)