m25p80: Add basic support for the SFDP command
JEDEC STANDARD JESD216 for Serial Flash Discovery Parameters (SFDP) provides a mean to describe the features of a serial flash device using a set of internal parameter tables. This is the initial framework for the RDSFDP command giving access to a private SFDP area under the flash. This area now needs to be populated with the flash device characteristics, using a new 'sfdp_read' handler under FlashPartInfo. Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com> Message-Id: <20220722063602.128144-2-clg@kaod.org> Message-Id: <20221013161241.2805140-2-clg@kaod.org> Signed-off-by: Cédric Le Goater <clg@kaod.org>
This commit is contained in:
parent
104bdaffd7
commit
2389bcc259
@ -1915,7 +1915,7 @@ SSI
|
||||
M: Alistair Francis <alistair@alistair23.me>
|
||||
S: Maintained
|
||||
F: hw/ssi/*
|
||||
F: hw/block/m25p80.c
|
||||
F: hw/block/m25p80*
|
||||
F: include/hw/ssi/ssi.h
|
||||
X: hw/ssi/xilinx_*
|
||||
F: tests/qtest/m25p80-test.c
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "qapi/error.h"
|
||||
#include "trace.h"
|
||||
#include "qom/object.h"
|
||||
#include "m25p80_sfdp.h"
|
||||
|
||||
/* 16 MiB max in 3 byte address mode */
|
||||
#define MAX_3BYTES_SIZE 0x1000000
|
||||
@ -72,6 +73,7 @@ typedef struct FlashPartInfo {
|
||||
* This field inform how many die is in the chip.
|
||||
*/
|
||||
uint8_t die_cnt;
|
||||
uint8_t (*sfdp_read)(uint32_t sfdp_addr);
|
||||
} FlashPartInfo;
|
||||
|
||||
/* adapted from linux */
|
||||
@ -355,6 +357,7 @@ typedef enum {
|
||||
BULK_ERASE = 0xc7,
|
||||
READ_FSR = 0x70,
|
||||
RDCR = 0x15,
|
||||
RDSFDP = 0x5a,
|
||||
|
||||
READ = 0x03,
|
||||
READ4 = 0x13,
|
||||
@ -421,6 +424,7 @@ typedef enum {
|
||||
STATE_COLLECTING_DATA,
|
||||
STATE_COLLECTING_VAR_LEN_DATA,
|
||||
STATE_READING_DATA,
|
||||
STATE_READING_SFDP,
|
||||
} CMDState;
|
||||
|
||||
typedef enum {
|
||||
@ -679,6 +683,8 @@ static inline int get_addr_length(Flash *s)
|
||||
}
|
||||
|
||||
switch (s->cmd_in_progress) {
|
||||
case RDSFDP:
|
||||
return 3;
|
||||
case PP4:
|
||||
case PP4_4:
|
||||
case QPP_4:
|
||||
@ -823,6 +829,11 @@ static void complete_collecting_data(Flash *s)
|
||||
" by device\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case RDSFDP:
|
||||
s->state = STATE_READING_SFDP;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1431,6 +1442,16 @@ static void decode_new_cmd(Flash *s, uint32_t value)
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Unknown cmd %x\n", value);
|
||||
}
|
||||
break;
|
||||
case RDSFDP:
|
||||
if (s->pi->sfdp_read) {
|
||||
s->needed_bytes = get_addr_length(s) + 1; /* SFDP addr + dummy */
|
||||
s->pos = 0;
|
||||
s->len = 0;
|
||||
s->state = STATE_COLLECTING_DATA;
|
||||
break;
|
||||
}
|
||||
/* Fallthrough */
|
||||
|
||||
default:
|
||||
s->pos = 0;
|
||||
s->len = 1;
|
||||
@ -1538,6 +1559,12 @@ static uint32_t m25p80_transfer8(SSIPeripheral *ss, uint32_t tx)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STATE_READING_SFDP:
|
||||
assert(s->pi->sfdp_read);
|
||||
r = s->pi->sfdp_read(s->cur_addr);
|
||||
trace_m25p80_read_sfdp(s, s->cur_addr, (uint8_t)r);
|
||||
s->cur_addr = (s->cur_addr + 1) & (M25P80_SFDP_MAX_SIZE - 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
case STATE_IDLE:
|
||||
|
18
hw/block/m25p80_sfdp.h
Normal file
18
hw/block/m25p80_sfdp.h
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* M25P80 SFDP
|
||||
*
|
||||
* Copyright (c) 2020, IBM Corporation.
|
||||
*
|
||||
* This code is licensed under the GPL version 2 or later. See the
|
||||
* COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
#ifndef HW_M25P80_SFDP_H
|
||||
#define HW_M25P80_SFDP_H
|
||||
|
||||
/*
|
||||
* SFDP area has a 3 bytes address space.
|
||||
*/
|
||||
#define M25P80_SFDP_MAX_SIZE (1 << 24)
|
||||
|
||||
#endif
|
@ -80,5 +80,6 @@ m25p80_page_program(void *s, uint32_t addr, uint8_t tx) "[%p] page program cur_a
|
||||
m25p80_transfer(void *s, uint8_t state, uint32_t len, uint8_t needed, uint32_t pos, uint32_t cur_addr, uint8_t t) "[%p] Transfer state 0x%"PRIx8" len 0x%"PRIx32" needed 0x%"PRIx8" pos 0x%"PRIx32" addr 0x%"PRIx32" tx 0x%"PRIx8
|
||||
m25p80_read_byte(void *s, uint32_t addr, uint8_t v) "[%p] Read byte 0x%"PRIx32"=0x%"PRIx8
|
||||
m25p80_read_data(void *s, uint32_t pos, uint8_t v) "[%p] Read data 0x%"PRIx32"=0x%"PRIx8
|
||||
m25p80_read_sfdp(void *s, uint32_t addr, uint8_t v) "[%p] Read SFDP 0x%"PRIx32"=0x%"PRIx8
|
||||
m25p80_binding(void *s) "[%p] Binding to IF_MTD drive"
|
||||
m25p80_binding_no_bdrv(void *s) "[%p] No BDRV - binding to RAM"
|
||||
|
Loading…
Reference in New Issue
Block a user