Skip to content

Commit

Permalink
libflash/mbox-flash: Implement MARK_WRITE_ERASED mbox call
Browse files Browse the repository at this point in the history
Version two of the mbox-flash protocol defines a new command:
MARK_WRITE_ERASED.

This command provides a simple way to mark a region of flash as all 0xff
without the need to go and write all 0xff. This is an optimisation as
there is no need for an erase before a write, it is the responsibility of
the BMC to deal with the flash correctly, however in v1 it was ambiguous
what a client should do if the flash should be erased but not actually
written to. This allows of a optimal path to resolve this problem.

Signed-off-by: Cyril Bur <cyril.bur@au1.ibm.com>
Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Acked-by: Cyril Bur <cyril.bur@au1.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
  • Loading branch information
sjitindarsingh authored and stewartsmith committed May 26, 2017
1 parent 3476c6e commit 3bb3f13
Showing 1 changed file with 59 additions and 4 deletions.
63 changes: 59 additions & 4 deletions libflash/mbox-flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,18 @@ static int mbox_flash_dirty(struct mbox_flash_data *mbox_flash, uint64_t pos,
MBOX_C_MARK_WRITE_DIRTY);
}

static int mbox_flash_erase(struct mbox_flash_data *mbox_flash, uint64_t pos,
uint64_t len)
{
if (!mbox_flash->write.open) {
prlog(PR_ERR, "Attempting to erase without an open write window\n");
return FLASH_ERR_DEVICE_GONE;
}

return mbox_flash_mark_write(mbox_flash, pos, len,
MBOX_C_MARK_WRITE_ERASED);
}

static int mbox_flash_flush(struct mbox_flash_data *mbox_flash)
{
struct bmc_mbox_msg *msg;
Expand Down Expand Up @@ -782,8 +794,50 @@ static int mbox_flash_get_info(struct blocklevel_device *bl, const char **name,
return rc;
}

static int mbox_flash_erase(struct blocklevel_device *bl __unused,
uint64_t pos __unused, uint64_t len __unused)
static int mbox_flash_erase_v2(struct blocklevel_device *bl, uint64_t pos,
uint64_t len)
{
struct mbox_flash_data *mbox_flash;

/* LPC is only 32bit */
if (pos > UINT_MAX || len > UINT_MAX)
return FLASH_ERR_PARM_ERROR;

mbox_flash = container_of(bl, struct mbox_flash_data, bl);

prlog(PR_TRACE, "Flash erase at 0x%08x for 0x%08x\n", (u32) pos, (u32) len);
while (len > 0) {
uint64_t size;
int rc;

/* Move window and get a new size to erase */
rc = mbox_window_move(mbox_flash, &mbox_flash->write,
MBOX_C_CREATE_WRITE_WINDOW, pos, len, &size);
if (rc)
return rc;

rc = mbox_flash_erase(mbox_flash, pos, size);
if (rc)
return rc;

/*
* Flush directly, don't mark that region dirty otherwise it
* isn't clear if a write happened there or not
*/

rc = mbox_flash_flush(mbox_flash);
if (rc)
return rc;

len -= size;
pos += size;
}

return 0;
}

static int mbox_flash_erase_v1(struct blocklevel_device *bl __unused,
uint64_t pos __unused, uint64_t len __unused)
{
/*
* We can probably get away with doing nothing.
Expand Down Expand Up @@ -880,7 +934,7 @@ static int protocol_init(struct mbox_flash_data *mbox_flash)
/* Assume V2 */
mbox_flash->bl.read = &mbox_flash_read;
mbox_flash->bl.write = &mbox_flash_write;
mbox_flash->bl.erase = &mbox_flash_erase;
mbox_flash->bl.erase = &mbox_flash_erase_v2;
mbox_flash->bl.get_info = &mbox_flash_get_info;

/* Assume V2 */
Expand Down Expand Up @@ -934,6 +988,7 @@ static int protocol_init(struct mbox_flash_data *mbox_flash)

prlog(PR_INFO, "Detected mbox protocol version %d\n", mbox_flash->version);
if (mbox_flash->version == 1) {
mbox_flash->bl.erase = &mbox_flash_erase_v1;
/* Not all handlers differ, update those which do */
mbox_flash->handlers[MBOX_C_GET_FLASH_INFO] = &mbox_flash_do_get_flash_info_v1;
mbox_flash->handlers[MBOX_C_CREATE_READ_WINDOW] =
Expand Down Expand Up @@ -976,7 +1031,7 @@ int mbox_flash_init(struct blocklevel_device **bl)
/* Assume V2 */
mbox_flash->bl.read = &mbox_flash_read;
mbox_flash->bl.write = &mbox_flash_write;
mbox_flash->bl.erase = &mbox_flash_erase;
mbox_flash->bl.erase = &mbox_flash_erase_v2;
mbox_flash->bl.get_info = &mbox_flash_get_info;

if (bmc_mbox_get_attn_reg() & MBOX_ATTN_BMC_REBOOT)
Expand Down

0 comments on commit 3bb3f13

Please sign in to comment.