[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH] m25p80.c Added support for N25Q256 and N25Q512
From: |
Krzeminski, Marcin (Nokia - PL/Wroclaw) |
Subject: |
[Qemu-devel] [PATCH] m25p80.c Added support for N25Q256 and N25Q512 |
Date: |
Sat, 28 Nov 2015 17:06:14 +0000 |
It is my first patch, so any comment are really welcome.
Changes:
* Removed unused variable
* Added support for n25q256a and n25q512a
* Added support for 4bytes address mode
* Added support for banked read mode
* Added support for sw reset flash commands
* Added Read Flag Status register command support
Signed-off-by: Marcin Krzeminski <address@hidden>
---
hw/block/m25p80.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 88 insertions(+), 6 deletions(-)
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index efc43dd..c8b92d8 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -47,6 +47,9 @@
*/
#define WR_1 0x100
+/* 16 MiB max in 3 byte address mode */
+#define MAX_3BYTES_SIZE 0x1000000
+
typedef struct FlashPartInfo {
const char *part_name;
/* jedec code. (jedec >> 16) & 0xff is the 1st byte, >> 8 the 2nd etc */
@@ -206,6 +209,8 @@ static const FlashPartInfo known_devices[] = {
/* Numonyx -- n25q128 */
{ INFO("n25q128", 0x20ba18, 0, 64 << 10, 256, 0) },
+ { INFO("n25q256a", 0x20ba19, 0, 64 << 10, 512, ER_4K) },
+ { INFO("n25q512a", 0x20ba20, 0, 64 << 10, 1024, ER_4K) },
};
typedef enum {
@@ -216,6 +221,7 @@ typedef enum {
WREN = 0x6,
JEDEC_READ = 0x9f,
BULK_ERASE = 0xc7,
+ READ_FSL = 0x70,
READ = 0x3,
FAST_READ = 0xb,
@@ -231,6 +237,15 @@ typedef enum {
ERASE_4K = 0x20,
ERASE_32K = 0x52,
ERASE_SECTOR = 0xd8,
+
+ ENTER_4BYTE_ADDR_MODE = 0xB7,
+ LEAVE_4BYTE_ADDR_MODE = 0xE9,
+
+ EXTEND_ADDR_READ = 0xC8,
+ EXTEND_ADDR_WRITE = 0xC5,
+
+ RESET_ENABLE = 0x66,
+ RESET_MEMORY = 0x99,
} FlashCMD;
typedef enum {
@@ -244,8 +259,6 @@ typedef enum {
typedef struct Flash {
SSISlave parent_obj;
- uint32_t r;
-
BlockBackend *blk;
uint8_t *storage;
@@ -260,6 +273,9 @@ typedef struct Flash {
uint8_t cmd_in_progress;
uint64_t cur_addr;
bool write_enable;
+ bool four_bytes_address_mode;
+ bool reset_enable;
+ uint8_t extended_addr_reg;
int64_t dirty_page;
@@ -397,9 +413,17 @@ void flash_write8(Flash *s, uint64_t addr, uint8_t data)
static void complete_collecting_data(Flash *s)
{
- s->cur_addr = s->data[0] << 16;
- s->cur_addr |= s->data[1] << 8;
- s->cur_addr |= s->data[2];
+ if (s->four_bytes_address_mode) {
+ s->cur_addr = s->data[0] << 24;
+ s->cur_addr |= s->data[1] << 16;
+ s->cur_addr |= s->data[2] << 8;
+ s->cur_addr |= s->data[3];
+ } else {
+ s->cur_addr = s->data[0] << 16;
+ s->cur_addr |= s->data[1] << 8;
+ s->cur_addr |= s->data[2];
+ s->cur_addr += (s->extended_addr_reg&0x3)*MAX_3BYTES_SIZE;
+ }
s->state = STATE_IDLE;
@@ -427,11 +452,28 @@ static void complete_collecting_data(Flash *s)
s->write_enable = false;
}
break;
+ case EXTEND_ADDR_WRITE:
+ s->extended_addr_reg = s->data[0];
+ break;
default:
break;
}
}
+static void reset_memory(Flash *s)
+{
+ s->cmd_in_progress = NOP;
+ s->cur_addr = 0;
+ s->extended_addr_reg = 0;
+ s->four_bytes_address_mode = false;
+ s->len = 0;
+ s->needed_bytes = 0;
+ s->pos = 0;
+ s->state = STATE_IDLE;
+ s->write_enable = false;
+ s->reset_enable = false;
+}
+
static void decode_new_cmd(Flash *s, uint32_t value)
{
s->cmd_in_progress = value;
@@ -446,7 +488,7 @@ static void decode_new_cmd(Flash *s, uint32_t value)
case DPP:
case QPP:
case PP:
- s->needed_bytes = 3;
+ s->needed_bytes = s->four_bytes_address_mode ? 4 : 3;
s->pos = 0;
s->len = 0;
s->state = STATE_COLLECTING_DATA;
@@ -514,6 +556,13 @@ static void decode_new_cmd(Flash *s, uint32_t value)
s->state = STATE_READING_DATA;
break;
+ case READ_FSL:
+ s->data[0] = (1<<7); /*Indicates flash is ready */
+ s->pos = 0;
+ s->len = 1;
+ s->state = STATE_READING_DATA;
+ break;
+
case JEDEC_READ:
DB_PRINT_L(0, "populated jedec code\n");
s->data[0] = (s->pi->jedec >> 16) & 0xff;
@@ -541,6 +590,34 @@ static void decode_new_cmd(Flash *s, uint32_t value)
break;
case NOP:
break;
+ case ENTER_4BYTE_ADDR_MODE:
+ s->four_bytes_address_mode = true;
+ break;
+ case LEAVE_4BYTE_ADDR_MODE:
+ s->four_bytes_address_mode = false;
+ break;
+ case EXTEND_ADDR_READ:
+ s->data[0] = s->extended_addr_reg;
+ s->pos = 0;
+ s->len = 1;
+ s->state = STATE_READING_DATA;
+ break;
+ case EXTEND_ADDR_WRITE:
+ if (s->write_enable) {
+ s->needed_bytes = 1;
+ s->pos = 0;
+ s->len = 0;
+ s->state = STATE_COLLECTING_DATA;
+ }
+ break;
+ case RESET_ENABLE:
+ s->reset_enable = true;
+ break;
+ case RESET_MEMORY:
+ if (s->reset_enable) {
+ reset_memory(s);
+ }
+ break;
default:
qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Unknown cmd %x\n", value);
break;
@@ -622,6 +699,8 @@ static int m25p80_init(SSISlave *ss)
s->size = s->pi->sector_size * s->pi->n_sectors;
s->dirty_page = -1;
+ reset_memory(s);
+
/* FIXME use a qdev drive property instead of drive_get_next() */
dinfo = drive_get_next(IF_MTD);
@@ -666,6 +745,9 @@ static const VMStateDescription vmstate_m25p80 = {
VMSTATE_UINT8(cmd_in_progress, Flash),
VMSTATE_UINT64(cur_addr, Flash),
VMSTATE_BOOL(write_enable, Flash),
+ VMSTATE_BOOL(four_bytes_address_mode, Flash),
+ VMSTATE_UINT8(extended_addr_reg, Flash),
+ VMSTATE_BOOL(reset_enable, Flash),
VMSTATE_END_OF_LIST()
}
};
--
1.9.1
Regards,
Marcin Krzeminski
- [Qemu-devel] [PATCH] m25p80.c Added support for N25Q256 and N25Q512,
Krzeminski, Marcin (Nokia - PL/Wroclaw) <=
- Re: [Qemu-devel] [PATCH] m25p80.c Added support for N25Q256 and N25Q512, Peter Crosthwaite, 2015/11/28
- Re: [Qemu-devel] [PATCH] m25p80.c Added support for N25Q256 and N25Q512, Krzeminski, Marcin (Nokia - PL/Wroclaw), 2015/11/29
- Re: [Qemu-devel] [PATCH] m25p80.c Added support for N25Q256 and N25Q512, Peter Crosthwaite, 2015/11/29
- Re: [Qemu-devel] [PATCH] m25p80.c Added support for N25Q256 and N25Q512, Krzeminski, Marcin (Nokia - PL/Wroclaw), 2015/11/30
- Re: [Qemu-devel] [PATCH] m25p80.c Added support for N25Q256 and N25Q512, Peter Crosthwaite, 2015/11/30
- Re: [Qemu-devel] [PATCH] m25p80.c Added support for N25Q256 and N25Q512, Krzeminski, Marcin (Nokia - PL/Wroclaw), 2015/11/30
- Re: [Qemu-devel] [PATCH] m25p80.c Added support for N25Q256 and N25Q512, Peter Crosthwaite, 2015/11/30