Commit a336e43a authored by Andrew Jeffery's avatar Andrew Jeffery
Browse files

protocol: Add mark_dirty


Change-Id: I192b96fa02a2266dd55ee97e5f4a751b45e3ae77
Signed-off-by: Andrew Jeffery's avatarAndrew Jeffery <andrew@aj.id.au>
parent 4bcec8ef
......@@ -130,6 +130,45 @@ int protocol_v1_create_window(struct mbox_context *context,
return 0;
}
int protocol_v1_mark_dirty(struct mbox_context *context,
struct protocol_mark_dirty *io)
{
uint32_t offset = io->req.v1.offset;
uint32_t size = io->req.v1.size;
uint32_t off;
if (!(context->current && context->current_is_write)) {
MSG_ERR("Tried to call mark dirty without open write window\n");
return -EPERM;
}
/* For V1 offset given relative to flash - we want the window */
off = offset - ((context->current->flash_offset) >>
context->block_size_shift);
if (off > offset) { /* Underflow - before current window */
MSG_ERR("Tried to mark dirty before start of window\n");
MSG_ERR("requested offset: 0x%x window start: 0x%x\n",
offset << context->block_size_shift,
context->current->flash_offset);
return -EINVAL;
}
offset = off;
/*
* We only track dirty at the block level.
* For protocol V1 we can get away with just marking the whole
* block dirty.
*/
size = align_up(size, 1 << context->block_size_shift);
size >>= context->block_size_shift;
MSG_INFO("Dirty window @ 0x%.8x for 0x%.8x\n",
offset << context->block_size_shift,
size << context->block_size_shift);
return window_set_bytemap(context, context->current, offset, size,
WINDOW_DIRTY);
}
/*
* get_suggested_timeout() - get the suggested timeout value in seconds
* @context: The mbox context pointer
......@@ -210,11 +249,28 @@ int protocol_v2_create_window(struct mbox_context *context,
return 0;
}
int protocol_v2_mark_dirty(struct mbox_context *context,
struct protocol_mark_dirty *io)
{
if (!(context->current && context->current_is_write)) {
MSG_ERR("Tried to call mark dirty without open write window\n");
return -EPERM;
}
MSG_INFO("Dirty window @ 0x%.8x for 0x%.8x\n",
io->req.v2.offset << context->block_size_shift,
io->req.v2.size << context->block_size_shift);
return window_set_bytemap(context, context->current, io->req.v2.offset,
io->req.v2.size, WINDOW_DIRTY);
}
static const struct protocol_ops protocol_ops_v1 = {
.reset = protocol_v1_reset,
.get_info = protocol_v1_get_info,
.get_flash_info = protocol_v1_get_flash_info,
.create_window = protocol_v1_create_window,
.mark_dirty = protocol_v1_mark_dirty,
};
static const struct protocol_ops protocol_ops_v2 = {
......@@ -222,6 +278,7 @@ static const struct protocol_ops protocol_ops_v2 = {
.get_info = protocol_v2_get_info,
.get_flash_info = protocol_v2_get_flash_info,
.create_window = protocol_v2_create_window,
.mark_dirty = protocol_v2_mark_dirty,
};
static const struct protocol_ops *protocol_ops_map[] = {
......
......@@ -58,6 +58,21 @@ struct protocol_create_window {
} resp;
};
struct protocol_mark_dirty {
struct {
union {
struct {
uint16_t offset;
uint32_t size;
} v1;
struct {
uint16_t offset;
uint16_t size;
} v2;
};
} req;
};
struct protocol_ops {
int (*reset)(struct mbox_context *context);
int (*get_info)(struct mbox_context *context,
......@@ -66,6 +81,8 @@ struct protocol_ops {
struct protocol_get_flash_info *io);
int (*create_window)(struct mbox_context *context,
struct protocol_create_window *io);
int (*mark_dirty)(struct mbox_context *context,
struct protocol_mark_dirty *io);
};
int protocol_init(struct mbox_context *context);
......@@ -81,6 +98,8 @@ int protocol_v1_get_flash_info(struct mbox_context *context,
struct protocol_get_flash_info *io);
int protocol_v1_create_window(struct mbox_context *context,
struct protocol_create_window *io);
int protocol_v1_mark_dirty(struct mbox_context *context,
struct protocol_mark_dirty *io);
/* Protocol v2 */
int protocol_v2_get_info(struct mbox_context *context,
......@@ -89,5 +108,7 @@ int protocol_v2_get_flash_info(struct mbox_context *context,
struct protocol_get_flash_info *io);
int protocol_v2_create_window(struct mbox_context *context,
struct protocol_create_window *io);
int protocol_v2_mark_dirty(struct mbox_context *context,
struct protocol_mark_dirty *io);
#endif /* PROTOCOL_H */
......@@ -387,51 +387,20 @@ int mbox_handle_write_window(struct mbox_context *context,
int mbox_handle_dirty_window(struct mbox_context *context,
union mbox_regs *req, struct mbox_msg *resp)
{
uint32_t offset, size;
struct protocol_mark_dirty io;
int rc;
if (!(context->current && context->current_is_write)) {
MSG_ERR("Tried to call mark dirty without open write window\n");
return context->version >= API_VERSION_2 ? -MBOX_R_WINDOW_ERROR
: -MBOX_R_PARAM_ERROR;
}
offset = get_u16(&req->msg.args[0]);
if (context->version >= API_VERSION_2) {
size = get_u16(&req->msg.args[2]);
if (context->version == API_VERSION_1) {
io.req.v1.offset = get_u16(&req->msg.args[0]);
io.req.v1.size = get_u32(&req->msg.args[2]);
} else {
uint32_t off;
/* For V1 offset given relative to flash - we want the window */
off = offset - ((context->current->flash_offset) >>
context->block_size_shift);
if (off > offset) { /* Underflow - before current window */
MSG_ERR("Tried to mark dirty before start of window\n");
MSG_ERR("requested offset: 0x%x window start: 0x%x\n",
offset << context->block_size_shift,
context->current->flash_offset);
return -MBOX_R_PARAM_ERROR;
}
offset = off;
size = get_u32(&req->msg.args[2]);
/*
* We only track dirty at the block level.
* For protocol V1 we can get away with just marking the whole
* block dirty.
*/
size = align_up(size, 1 << context->block_size_shift);
size >>= context->block_size_shift;
}
MSG_INFO("Dirty window @ 0x%.8x for 0x%.8x\n",
offset << context->block_size_shift,
size << context->block_size_shift);
io.req.v2.offset = get_u16(&req->msg.args[0]);
io.req.v2.size = get_u16(&req->msg.args[2]);
}
rc = window_set_bytemap(context, context->current, offset, size,
WINDOW_DIRTY);
rc = context->protocol->mark_dirty(context, &io);
if (rc < 0) {
return (rc == -EACCES) ? -MBOX_R_PARAM_ERROR
: -MBOX_R_SYSTEM_ERROR;
return mbox_xlate_errno(context, rc);
}
return rc;
......
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