Commit 26f7e64c authored by Carl-Daniel Hailfinger's avatar Carl-Daniel Hailfinger
Browse files

The current ICH SPI preop handling is a hack which spews lots of warnings, but...

The current ICH SPI preop handling is a hack which spews lots of warnings, but still yields correct results

With the multicommand infrastructure I introduced in r645, it became
possible to integrate ICH SPI preopcodes cleanly into the flashrom
design.

The new code checks for every opcode in a multicommand array if it is a
preopcode. If yes, it checks if the next opcode is associated with that
preopcode and in that case it simply runs the opcode because the correct
preopcode will be run automatically before the opcode.

Corresponding to flashrom svn r727.
Signed-off-by: default avatarCarl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
Acked-by: default avatarFENG Yu Ning <fengyuning1984@gmail.com>
parent 707f1ebe
......@@ -498,7 +498,7 @@ struct spi_command {
struct spi_programmer {
int (*command)(unsigned int writecnt, unsigned int readcnt,
const unsigned char *writearr, unsigned char *readarr);
int (*multicommand)(struct spi_command *spicommands);
int (*multicommand)(struct spi_command *cmds);
/* Optimized functions for this programmer */
int (*read)(struct flashchip *flash, uint8_t *buf, int start, int len);
......@@ -514,7 +514,7 @@ int probe_spi_rems(struct flashchip *flash);
int probe_spi_res(struct flashchip *flash);
int spi_send_command(unsigned int writecnt, unsigned int readcnt,
const unsigned char *writearr, unsigned char *readarr);
int spi_send_multicommand(struct spi_command *spicommands);
int spi_send_multicommand(struct spi_command *cmds);
int spi_write_enable(void);
int spi_write_disable(void);
int spi_chip_erase_60(struct flashchip *flash);
......@@ -539,7 +539,7 @@ int spi_aai_write(struct flashchip *flash, uint8_t *buf);
uint32_t spi_get_valid_read_addr(void);
int default_spi_send_command(unsigned int writecnt, unsigned int readcnt,
const unsigned char *writearr, unsigned char *readarr);
int default_spi_send_multicommand(struct spi_command *spicommands);
int default_spi_send_multicommand(struct spi_command *cmds);
/* 82802ab.c */
int probe_82802ab(struct flashchip *flash);
......@@ -565,7 +565,7 @@ int ich_spi_send_command(unsigned int writecnt, unsigned int readcnt,
const unsigned char *writearr, unsigned char *readarr);
int ich_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
int ich_spi_write_256(struct flashchip *flash, uint8_t * buf);
int ich_spi_send_multicommand(struct spi_command *spicommands);
int ich_spi_send_multicommand(struct spi_command *cmds);
/* it87spi.c */
extern uint16_t it8716f_flashport;
......
......@@ -742,22 +742,29 @@ int ich_spi_send_command(unsigned int writecnt, unsigned int readcnt,
return result;
}
int ich_spi_send_multicommand(struct spi_command *spicommands)
int ich_spi_send_multicommand(struct spi_command *cmds)
{
int ret = 0;
while ((spicommands->writecnt || spicommands->readcnt) && !ret) {
ret = ich_spi_send_command(spicommands->writecnt, spicommands->readcnt,
spicommands->writearr, spicommands->readarr);
/* This awful hack needs to be smarter.
*/
if ((ret == SPI_INVALID_OPCODE) &&
((spicommands->writearr[0] == JEDEC_WREN) ||
(spicommands->writearr[0] == JEDEC_EWSR))) {
printf_debug(" due to SPI master limitation, ignoring"
" and hoping it will be run as PREOP\n");
ret = 0;
}
spicommands++;
int oppos, preoppos;
for (; (cmds->writecnt || cmds->readcnt) && !ret; cmds++) {
/* Is the next command valid or a terminator? */
if ((cmds + 1)->writecnt || (cmds + 1)->readcnt) {
preoppos = find_preop(curopcodes, cmds->writearr[0]);
oppos = find_opcode(curopcodes, (cmds + 1)->writearr[0]);
/* Is the opcode of the current command listed in the
* ICH struct OPCODES as associated preopcode for the
* opcode of the next command?
*/
if ((oppos != -1) && (preoppos != -1) &&
(curopcodes->opcode[oppos].atomic - 1 == preoppos)) {
printf_debug("opcode 0x%02x will be run as PREOP\n",
cmds->writearr[0]);
continue;
}
}
ret = ich_spi_send_command(cmds->writecnt, cmds->readcnt,
cmds->writearr, cmds->readarr);
}
return ret;
}
......@@ -118,7 +118,7 @@ int spi_send_command(unsigned int writecnt, unsigned int readcnt,
writearr, readarr);
}
int spi_send_multicommand(struct spi_command *spicommands)
int spi_send_multicommand(struct spi_command *cmds)
{
if (!spi_programmer[spi_controller].multicommand) {
fprintf(stderr, "%s called, but SPI is unsupported on this "
......@@ -126,7 +126,7 @@ int spi_send_multicommand(struct spi_command *spicommands)
return 1;
}
return spi_programmer[spi_controller].multicommand(spicommands);
return spi_programmer[spi_controller].multicommand(cmds);
}
int default_spi_send_command(unsigned int writecnt, unsigned int readcnt,
......@@ -148,13 +148,12 @@ int default_spi_send_command(unsigned int writecnt, unsigned int readcnt,
return spi_send_multicommand(cmd);
}
int default_spi_send_multicommand(struct spi_command *spicommands)
int default_spi_send_multicommand(struct spi_command *cmds)
{
int result = 0;
while ((spicommands->writecnt || spicommands->readcnt) && !result) {
result = spi_send_command(spicommands->writecnt, spicommands->readcnt,
spicommands->writearr, spicommands->readarr);
spicommands++;
for (; (cmds->writecnt || cmds->readcnt) && !result; cmds++) {
result = spi_send_command(cmds->writecnt, cmds->readcnt,
cmds->writearr, cmds->readarr);
}
return result;
}
......@@ -494,7 +493,7 @@ void spi_prettyprint_status_register(struct flashchip *flash)
int spi_chip_erase_60(struct flashchip *flash)
{
int result;
struct spi_command spicommands[] = {
struct spi_command cmds[] = {
{
.writecnt = JEDEC_WREN_OUTSIZE,
.writearr = (const unsigned char[]){ JEDEC_WREN },
......@@ -518,7 +517,7 @@ int spi_chip_erase_60(struct flashchip *flash)
return result;
}
result = spi_send_multicommand(spicommands);
result = spi_send_multicommand(cmds);
if (result) {
fprintf(stderr, "%s failed during command execution\n",
__func__);
......@@ -540,7 +539,7 @@ int spi_chip_erase_60(struct flashchip *flash)
int spi_chip_erase_c7(struct flashchip *flash)
{
int result;
struct spi_command spicommands[] = {
struct spi_command cmds[] = {
{
.writecnt = JEDEC_WREN_OUTSIZE,
.writearr = (const unsigned char[]){ JEDEC_WREN },
......@@ -564,7 +563,7 @@ int spi_chip_erase_c7(struct flashchip *flash)
return result;
}
result = spi_send_multicommand(spicommands);
result = spi_send_multicommand(cmds);
if (result) {
fprintf(stderr, "%s failed during command execution\n", __func__);
return result;
......@@ -596,7 +595,7 @@ int spi_chip_erase_60_c7(struct flashchip *flash)
int spi_block_erase_52(struct flashchip *flash, unsigned int addr, unsigned int blocklen)
{
int result;
struct spi_command spicommands[] = {
struct spi_command cmds[] = {
{
.writecnt = JEDEC_WREN_OUTSIZE,
.writearr = (const unsigned char[]){ JEDEC_WREN },
......@@ -614,7 +613,7 @@ int spi_block_erase_52(struct flashchip *flash, unsigned int addr, unsigned int
.readarr = NULL,
}};
result = spi_send_multicommand(spicommands);
result = spi_send_multicommand(cmds);
if (result) {
fprintf(stderr, "%s failed during command execution\n",
__func__);
......@@ -640,7 +639,7 @@ int spi_block_erase_52(struct flashchip *flash, unsigned int addr, unsigned int
int spi_block_erase_d8(struct flashchip *flash, unsigned int addr, unsigned int blocklen)
{
int result;
struct spi_command spicommands[] = {
struct spi_command cmds[] = {
{
.writecnt = JEDEC_WREN_OUTSIZE,
.writearr = (const unsigned char[]){ JEDEC_WREN },
......@@ -658,7 +657,7 @@ int spi_block_erase_d8(struct flashchip *flash, unsigned int addr, unsigned int
.readarr = NULL,
}};
result = spi_send_multicommand(spicommands);
result = spi_send_multicommand(cmds);
if (result) {
fprintf(stderr, "%s failed during command execution\n", __func__);
return result;
......@@ -702,7 +701,7 @@ int spi_chip_erase_d8(struct flashchip *flash)
int spi_block_erase_20(struct flashchip *flash, unsigned int addr, unsigned int blocklen)
{
int result;
struct spi_command spicommands[] = {
struct spi_command cmds[] = {
{
.writecnt = JEDEC_WREN_OUTSIZE,
.writearr = (const unsigned char[]){ JEDEC_WREN },
......@@ -720,7 +719,7 @@ int spi_block_erase_20(struct flashchip *flash, unsigned int addr, unsigned int
.readarr = NULL,
}};
result = spi_send_multicommand(spicommands);
result = spi_send_multicommand(cmds);
if (result) {
fprintf(stderr, "%s failed during command execution\n",
__func__);
......@@ -779,7 +778,7 @@ int spi_write_status_enable(void)
int spi_write_status_register(int status)
{
int result;
struct spi_command spicommands[] = {
struct spi_command cmds[] = {
{
.writecnt = JEDEC_EWSR_OUTSIZE,
.writearr = (const unsigned char[]){ JEDEC_EWSR },
......@@ -797,7 +796,7 @@ int spi_write_status_register(int status)
.readarr = NULL,
}};
result = spi_send_multicommand(spicommands);
result = spi_send_multicommand(cmds);
if (result) {
fprintf(stderr, "%s failed during command execution\n",
__func__);
......@@ -808,7 +807,7 @@ int spi_write_status_register(int status)
int spi_byte_program(int addr, uint8_t byte)
{
int result;
struct spi_command spicommands[] = {
struct spi_command cmds[] = {
{
.writecnt = JEDEC_WREN_OUTSIZE,
.writearr = (const unsigned char[]){ JEDEC_WREN },
......@@ -826,7 +825,7 @@ int spi_byte_program(int addr, uint8_t byte)
.readarr = NULL,
}};
result = spi_send_multicommand(spicommands);
result = spi_send_multicommand(cmds);
if (result) {
fprintf(stderr, "%s failed during command execution\n",
__func__);
......@@ -844,7 +843,7 @@ int spi_nbyte_program(int address, uint8_t *bytes, int len)
(address >> 8) & 0xff,
(address >> 0) & 0xff,
};
struct spi_command spicommands[] = {
struct spi_command cmds[] = {
{
.writecnt = JEDEC_WREN_OUTSIZE,
.writearr = (const unsigned char[]){ JEDEC_WREN },
......@@ -873,7 +872,7 @@ int spi_nbyte_program(int address, uint8_t *bytes, int len)
memcpy(&cmd[4], bytes, len);
result = spi_send_multicommand(spicommands);
result = spi_send_multicommand(cmds);
if (result) {
fprintf(stderr, "%s failed during command execution\n",
__func__);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment