Commit 22fa5009 authored by Andrew Jeffery's avatar Andrew Jeffery
Browse files

protocol: Add create_read_window


Change-Id: I82e9e69861163fb1ae35313fcfee37e03be69f65
Signed-off-by: Andrew Jeffery's avatarAndrew Jeffery <andrew@aj.id.au>
parent 91a87454
......@@ -133,6 +133,7 @@ union mbox_regs {
};
struct mbox_context;
typedef int (*mboxd_mbox_handler)(struct mbox_context *, union mbox_regs *,
struct mbox_msg *);
......
......@@ -62,6 +62,72 @@ int protocol_v1_get_flash_info(struct mbox_context *context,
return 0;
}
/*
* get_lpc_addr_shifted() - Get lpc address of the current window
* @context: The mbox context pointer
*
* Return: The lpc address to access that offset shifted by block size
*/
static inline uint16_t get_lpc_addr_shifted(struct mbox_context *context)
{
uint32_t lpc_addr, mem_offset;
/* Offset of the current window in the reserved memory region */
mem_offset = context->current->mem - context->mem;
/* Total LPC Address */
lpc_addr = context->lpc_base + mem_offset;
MSG_DBG("LPC address of current window: 0x%.8x\n", lpc_addr);
return lpc_addr >> context->block_size_shift;
}
int protocol_v1_create_read_window(struct mbox_context *context,
struct protocol_create_window *io)
{
int rc;
uint32_t offset = io->req.offset << context->block_size_shift;
/* Close the current window if there is one */
if (context->current) {
/* There is an implicit flush if it was a write window */
if (context->current_is_write) {
rc = mbox_handle_flush_window(context, NULL, NULL);
if (rc < 0) {
MSG_ERR("Couldn't Flush Write Window\n");
return rc;
}
}
windows_close_current(context, NO_BMC_EVENT, FLAGS_NONE);
}
/* Offset the host has requested */
MSG_INFO("Host requested flash @ 0x%.8x\n", offset);
/* Check if we have an existing window */
context->current = windows_search(context, offset,
context->version == API_VERSION_1);
if (!context->current) { /* No existing window */
MSG_DBG("No existing window which maps that flash offset\n");
rc = windows_create_map(context, &context->current,
offset,
context->version == API_VERSION_1);
if (rc < 0) { /* Unable to map offset */
MSG_ERR("Couldn't create window mapping for offset 0x%.8x\n",
io->req.offset);
return rc;
}
}
MSG_INFO("Window @ %p for size 0x%.8x maps flash offset 0x%.8x\n",
context->current->mem, context->current->size,
context->current->flash_offset);
io->resp.lpc_address = get_lpc_addr_shifted(context);
return 0;
}
/*
* get_suggested_timeout() - get the suggested timeout value in seconds
* @context: The mbox context pointer
......@@ -126,16 +192,35 @@ int protocol_v2_get_flash_info(struct mbox_context *context,
return 0;
}
int protocol_v2_create_read_window(struct mbox_context *context,
struct protocol_create_window *io)
{
int rc;
rc = protocol_v1_create_read_window(context, io);
if (rc < 0)
return rc;
io->resp.size = context->current->size >> context->block_size_shift;
io->resp.offset = context->current->flash_offset >>
context->block_size_shift;
return 0;
}
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_read_window = protocol_v1_create_read_window,
};
static const struct protocol_ops protocol_ops_v2 = {
.reset = protocol_v1_reset,
.get_info = protocol_v2_get_info,
.get_flash_info = protocol_v2_get_flash_info,
.create_read_window = protocol_v2_create_read_window,
};
static const struct protocol_ops *protocol_ops_map[] = {
......
......@@ -44,12 +44,27 @@ struct protocol_get_flash_info {
} resp;
};
struct protocol_create_window {
struct {
uint16_t offset;
uint16_t size;
uint8_t id;
} req;
struct {
uint16_t lpc_address;
uint16_t size;
uint16_t offset;
} resp;
};
struct protocol_ops {
int (*reset)(struct mbox_context *context);
int (*get_info)(struct mbox_context *context,
struct protocol_get_info *io);
int (*get_flash_info)(struct mbox_context *context,
struct protocol_get_flash_info *io);
int (*create_read_window)(struct mbox_context *context,
struct protocol_create_window *io);
};
int protocol_init(struct mbox_context *context);
......@@ -63,11 +78,15 @@ int protocol_v1_get_info(struct mbox_context *context,
struct protocol_get_info *io);
int protocol_v1_get_flash_info(struct mbox_context *context,
struct protocol_get_flash_info *io);
int protocol_v1_create_read_window(struct mbox_context *context,
struct protocol_create_window *io);
/* Protocol v2 */
int protocol_v2_get_info(struct mbox_context *context,
struct protocol_get_info *io);
int protocol_v2_get_flash_info(struct mbox_context *context,
struct protocol_get_flash_info *io);
int protocol_v2_create_read_window(struct mbox_context *context,
struct protocol_create_window *io);
#endif /* PROTOCOL_H */
......@@ -307,50 +307,20 @@ static inline uint16_t get_lpc_addr_shifted(struct mbox_context *context)
int mbox_handle_read_window(struct mbox_context *context,
union mbox_regs *req, struct mbox_msg *resp)
{
uint32_t flash_offset;
struct protocol_create_window io;
int rc;
/* Close the current window if there is one */
if (context->current) {
/* There is an implicit flush if it was a write window */
if (context->current_is_write) {
rc = mbox_handle_flush_window(context, NULL, NULL);
if (rc < 0) {
MSG_ERR("Couldn't Flush Write Window\n");
return rc;
}
}
windows_close_current(context, NO_BMC_EVENT, FLAGS_NONE);
}
/* Offset the host has requested */
flash_offset = get_u16(&req->msg.args[0]) << context->block_size_shift;
MSG_INFO("Host requested flash @ 0x%.8x\n", flash_offset);
/* Check if we have an existing window */
context->current = windows_search(context, flash_offset,
context->version == API_VERSION_1);
if (!context->current) { /* No existing window */
MSG_DBG("No existing window which maps that flash offset\n");
rc = windows_create_map(context, &context->current, flash_offset,
context->version == API_VERSION_1);
if (rc < 0) { /* Unable to map offset */
MSG_ERR("Couldn't create window mapping for offset 0x%.8x\n"
, flash_offset);
return rc;
}
}
io.req.offset = get_u16(&req->msg.args[0]);
MSG_INFO("Window @ %p for size 0x%.8x maps flash offset 0x%.8x\n",
context->current->mem, context->current->size,
context->current->flash_offset);
rc = context->protocol->create_read_window(context, &io);
if (rc < 0) {
return mbox_xlate_errno(context, rc);
}
put_u16(&resp->args[0], get_lpc_addr_shifted(context));
put_u16(&resp->args[0], io.resp.lpc_address);
if (context->version >= API_VERSION_2) {
put_u16(&resp->args[2], context->current->size >>
context->block_size_shift);
put_u16(&resp->args[4], context->current->flash_offset >>
context->block_size_shift);
put_u16(&resp->args[2], io.resp.size);
put_u16(&resp->args[4], io.resp.offset);
}
context->current_is_write = false;
......
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